Files
SGF/docs/MODULE_ASSOCIATION_CONCURRENCY_REVIEW.md
T
2026-11-02 20:29:34 +02:00

9.1 KiB

Fila de associações — leituras concorrentes e confirmação

Continuação de 02/11/2026: a consolidação de carga e libertação dos bloqueios identifica a espera no FOR UPDATE da empresa e verifica quatro resultados após commit/rollback, sem duplicação. As 440 leituras deste relatório foram preservadas e não repetidas. A limitação de não observar o resultado após libertação, nesta prova original, é agora coberta pela prova separada; a capacidade de implantação continua pendente.

02/11/2026. Continuação da projecção de referências, sem alterar o código funcional já medido. Avaliação nova de concorrência sintética, sem repetir as suites válidas anteriores. A revisão visual e a capacidade de implantação continuam separadas.

Âmbito e preparação

PHP 8.4.27; base sgf_tempo_test, role sgf_test_runner, cluster sgf_modular_regression_2576427d1939, porta 55439. Foram preparados 3 000 registos por área, 25 pares de rascunhos com 100 linhas/serviços distintos por rascunho e descrições de 1 000 bytes por linha. A página de 25 rascunhos referencia 2 500 serviços. Existe ruído de outro tenant e unidade não seleccionada, como nas fixtures anteriores.

São quatro identidades sintéticas novas, com consulta administrativa explicitamente configurada apenas no novo âmbito QA. Uma identidade dispõe também de clients.edit nesse âmbito para a confirmação sintética desfeita. Não se modificaram contas/direitos da instalação SGF, de 8039 ou de outros âmbitos anteriores.

Para processos independentes verem as mesmas linhas, a nova fixture foi gravada exclusivamente na base de regressão e ficou retida, com manifesto privado fora da raiz web/repositório. Não se declara rollback desta preparação. Não se apagou ou reinicializou a base. O manifesto identifica o âmbito para diagnóstico; não contém palavras-passe. Entradas privadas dos trabalhadores contêm contexto/tokens de prova e não integram os artefactos públicos.

Foram usados 1/2/4 processos PHP independentes, cada um com identidade e sessão distintas, aquecimento e barreira de arranque. Há três ondas por cenário e cinco pedidos sequenciais por processo. Os leitores executam em transacção PostgreSQL READ ONLY, com timeout SQL de 3 s; o coordenador impõe prazos de arranque/conclusão e termina apenas os seus próprios processos em falha.

O pedido percorre o kernel HTTP, middleware, autorização e SQL reais, com autenticação previamente preparada. Não usa servidor HTTP externo, login/MFA, TLS, proxy, navegador ou sessões reais de cliente. O tempo de arranque dos processos foi registado separadamente e excluído da janela principal de leitura.

Resultados das leituras

Página de 25 registos. P50/P95 são percentis descritivos da amostra, pelo método nearest rank; não são garantias de cauda ou SLA. A taxa é a observada neste circuito fechado, incluindo validação entre pedidos, não capacidade máxima sustentada.

Índice na prova Área Processos Pedidos P50 ms P95 da amostra ms Pedidos/s observados
Sem índice experimental Clientes 1 15 35,86 51,07 24,61
Sem índice experimental Clientes 2 30 35,73 39,46 50,32
Sem índice experimental Clientes 4 60 37,99 60,81 80,58
Sem índice experimental Facturação, 100 linhas 1 15 298,01 476,93 3,11
Sem índice experimental Facturação, 100 linhas 2 30 264,37 358,30 6,92
Sem índice experimental Facturação, 100 linhas 4 60 429,46 495,43 9,57
Revisão experimental Clientes 1 15 11,54 13,48 65,64
Revisão experimental Clientes 2 30 11,08 12,16 132,32
Revisão experimental Clientes 4 60 14,79 21,40 207,56
Revisão experimental Facturação, 100 linhas 1 15 99,51 157,65 8,47
Revisão experimental Facturação, 100 linhas 2 30 102,92 188,29 14,36
Revisão experimental Facturação, 100 linhas 4 60 102,86 121,34 33,81

As 420 leituras da matriz concluíram, sem limites SQL atingidos. Os intervalos medidos confirmaram sobreposição efectiva de 1/2/4 pedidos em todas as ondas correspondentes, não apenas processos configurados. Cada resposta foi validada contra o hash esperado da fixture; identidades diferentes receberam a mesma resposta autorizada.

Mantiveram-se 11 consultas por pedido de clientes e 31 por pedido de facturação. A memória incremental máxima por processo/pedido ficou perto de 0,09 MiB e 4,85 MiB, respectivamente. Não se deve multiplicar esses valores para inferir o consumo total do servidor: faltam kernel/processos, PostgreSQL, sessões e demais serviços.

O índice experimental de revisão tinha nome único por execução. Foi gravado na base sintética para ficar visível aos outros processos e removido explicitamente no final. Não se declara rollback dessa criação entre processos. A ausência do índice foi verificada; o catálogo anterior ficou igual. Nenhum índice foi criado/removido no destino ou na demonstração persistente.

Leituras durante uma confirmação e espera de outro decisor

Numa transacção exterior, a API confirmou uma associação apenas para um cliente novo da fixture e manteve os bloqueios de empresa/registo. Enquanto a decisão permanecia sem commit, quatro leitores fizeram mais 20 pedidos, todos com a resposta anterior esperada e sobreposição efectiva de quatro. A leitura MVCC não expôs a decisão não gravada.

Uma segunda conferência do mesmo cliente chamou o serviço de confirmação noutro processo. Foi observada espera real em pg_stat_activity, seguida de SQLSTATE 55P03 ao atingir o lock_timeout=1000ms configurado exclusivamente nesse processo: cerca de 1 044 ms. O chamador directo registou o erro de base de dados; este cenário não mede a apresentação HTTP desse timeout ao utilizador.

A primeira transacção foi desfeita. A contagem de eventos de associação do novo âmbito permaneceu igual à anterior à prova; a segunda chamada não gravou decisão. Não se decidiu nenhuma das seis associações protegidas. As provas anteriores de confirmações concorrentes com commit normal continuam válidas e não foram repetidas nesta passagem.

Evidência e preservação

O coordenador passou 1 ensaio / 346 asserções. Recolheu ainda a conclusão dos 89 subprocessos de teste: 88 leitores (84 da matriz + quatro da prova mista) e um concorrente de confirmação. Total: 440 leituras medidas completas, mais o aquecimento; sem falhas nos leitores. Não se somam aqui as asserções internas dos trabalhadores às do coordenador.

Medições por onda/pedido · resumo, percentis e hashes.

Foram comparados os IDs e hashes das linhas que já existiam antes nas oito tabelas de registos/identidade, bem como o catálogo de índices, depois da prova. Permaneceram iguais. As novas linhas QA e quatro contas sintéticas são adicionais e retidas apenas nessa base; não são confundidas com preservação de contagem global ou com implantação de perfis. As sequências não foram repostas.

Os seis registos protegidos, a cache bloqueada, o código funcional e o trabalho alheio permaneceram intactos. Não houve ligação ao SGF local/8039, concessão real, publicação, activação de Compras ou novo checkpoint. Tokens, credenciais e manifestos privados não foram copiados para o relatório.

Limites e repetição

A carga é curta, em uma empresa/unidade, com quatro identidades e um único login PostgreSQL de QA; não valida multi-tenant concorrente, grande número de sessões, saturação, arranque frio, dimensionamento de pool, custo de escrita prolongada ou implantação/recuperação de índices. O cluster é partilhado com outra base sintética. Os valores descritivos das amostras de 15/30/60 pedidos não validam percentis de produção ou capacidade de implantação.

O ensaio não altera a política de timeout da aplicação. A espera controlada foi exercitada directamente no serviço; tratamento HTTP, retries operacionais e comunicação visual de um timeout continuam a precisar de avaliação própria. A revisão visual permanece pendente, sem nova tentativa pela via bloqueada.

O launcher fixado aceita scripts/module-association-compare.mjs concurrency, após sync da cópia de regressão existente. Uma nova execução cria outro âmbito sintético e um manifesto privado, pelo que deve ser deliberada; não repete por rotina testes válidos, não reseta a base e não remove as fixtures anteriores. Os trabalhadores só aceitam entradas privadas sob o directório da execução e conferem a identidade física da base. scripts/summarize-association-concurrency.mjs <relatorio-privado.json> gera o resumo sem executar testes ou consultar bases.

Esta prova amplia a evidência sintética de concorrência. Revisão visual, aceitação deste incremento e validação da capacidade de implantação continuam separadas.