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

80 lines
9.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fila de associações — referências, memória e índices isolados
Seguimento: [leituras concorrentes e confirmação individual](MODULE_ASSOCIATION_CONCURRENCY_REVIEW.md), com quatro identidades sintéticas e preservação dos dados anteriores da base de provas. A evidência adicional não constitui validação da capacidade de implantação ou revisão visual.
02/11/2026. Continuação local da [optimização da fila](MODULE_ASSOCIATION_OPTIMIZATION_DELIVERY.md). Foram tratados dois pontos que permaneciam por avaliar: documentos com **100 linhas** e a contribuição do índice de revisão sozinho versus o par experimental. A avaliação encontrou um custo de memória e originou uma melhoria adicional de código, sem alterar dados do destino.
## Alteração funcional
A fila passa a seleccionar apenas ID/versão, nome da raiz e referências explícitas. Para rascunhos, o PostgreSQL extrai os IDs de serviços das linhas com `WITH ORDINALITY`, preservando a ordem; descrições, preços e restantes conteúdos documentais não são transferidos para a cache de descrição da página. Dependências de clientes/serviços seleccionam apenas ID/versão.
O percurso, a deduplicação, os grupos de até 500 IDs, os filtros, as permissões e a forma da resposta continuam iguais. Os IDs calculados são internos e não acrescentam um campo público à API. Nenhuma associação é inferida ou propagada.
**A projecção só se aplica à listagem.** Prévia e confirmação continuam a carregar e a resumir criptograficamente os registos completos, incluindo conteúdo não apresentado na fila. O código desde `preview()` até `confirm()` continua igual ao de `340f3bb`, após normalizar fins de linha. Alterar conteúdo de uma dependência, mantendo as mesmas referências, continua a invalidar uma conferência anterior.
## Ensaio novo, sem repetir a comparação anterior
Base **sgf_tempo_test**, role **sgf_test_runner**, cluster **sgf_modular_regression_2576427d1939**, porta **55439**, PHP **8.4.27**. Foram reutilizados os resultados válidos anteriores; não se repetiu a matriz de 1 000/5 000/10 000 da primeira optimização, a regressão geral ou o build React.
A nova fixture contém **10 000 registos em cada uma das quatro áreas**. As primeiras 100 prestações e os seus 100 rascunhos de facturação têm 100 linhas, com blocos distintos de serviços: uma página de 100 referencia 10 000 serviços. Uma prestação apresenta 101 dependências; um rascunho de facturação, 102. Foram ensaiadas páginas de 25/100 e descrições sintéticas de **128 e 1 000 bytes por linha**.
As quatro variantes usam a mesma fixture por perfil: código anterior à projecção sem índices; projecção sem índices; projecção com índice de revisão; projecção com o par. A fonte anterior foi preservada antes da alteração, fora da raiz web, alterando apenas o nome da classe para a prova. O launcher verifica a integridade da cópia; os hashes original/final constam do resumo. Não se trata de um segundo percurso de produção.
São três amostras quentes e sequenciais por cenário, com recolha de ciclos PHP antes da medição e os mesmos limites diagnósticos: 3 s por SQL, 15 s observados entre consultas, 250 consultas e 192 MiB de memória PHP usada observada entre consultas. A configuração PHP existente é 512M e não foi alterada. Estes limites não são SLA ou quotas de produção.
## Memória incremental por pedido
Máximo observado nas três amostras, em **MiB**, excluindo a memória já usada pelo kernel e pela fixture. A comparação abaixo é sem índices, na mesma fixture antes/depois da projecção.
| Descrição por linha | Área | Página | Antes | Depois |
| ---: | --- | ---: | ---: | ---: |
| 128 bytes | Prestações | 25 | 6,13 | 4,21 |
| 128 bytes | Prestações | 100 | 24,11 | 16,65 |
| 128 bytes | Facturação | 25 | 7,34 | 4,85 |
| 128 bytes | Facturação | 100 | 28,98 | 19,23 |
| 1 000 bytes | Prestações | 25 | 8,28 | 4,21 |
| 1 000 bytes | Prestações | 100 | 32,42 | 16,65 |
| 1 000 bytes | Facturação | 25 | 11,55 | 4,85 |
| 1 000 bytes | Facturação | 100 | **45,49** | **19,23** |
No caso mais pesado, a redução foi de aproximadamente **58%**. A memória após a projecção deixou de crescer com as descrições destes perfis, mas continua a crescer com o número de dependências que a página tem de apresentar. Não se deve aplicar a estimativa anterior de cerca de 1 MiB, obtida com uma linha por rascunho, ao cenário de 100 linhas.
As consultas PDO mantiveram-se iguais antes/depois da projecção: prestações **27/57** e facturação **31/61**, para páginas de 25/100. O crescimento em relação à prova de uma linha deve-se aos grupos necessários para 2 500/10 000 serviços distintos, não a uma consulta por linha. As respostas de 100 registos ficaram perto de **0,79–0,80 MB**, sem descrições documentais e sem diferenças de bytes entre as variantes de cada perfil.
## Tempos e contribuição dos índices
Medianas em ms, descrições de 1 000 bytes por linha:
| Área / página | Antes, sem índices | Projecção, sem índices | Só revisão | Par experimental |
| --- | ---: | ---: | ---: | ---: |
| Prestações / 25 | 668 | 729 | 97 | 226 |
| Prestações / 100 | 2 151 | 2 862 | 341 | 408 |
| Facturação / 25 | 815 | 905 | 112 | 127 |
| Facturação / 100 | 2 721 | 2 481 | 374 | 368 |
O benefício demonstrado da projecção é a memória e o menor conteúdo transportado para o PHP. **Não acelerou todos os casos sem índices**; houve também aumentos de latência, por exemplo nas prestações de 100. As fases têm ordem fixa e o cluster é partilhado com outra base sintética, pelo que três amostras não permitem atribuir toda a variação à alteração de código.
Na condição de 128 bytes, os filtros de clientes sem eventos/associados/retirados ficaram em **109/219/262 ms** com o índice de revisão e **117/235/278 ms** com o par. O segundo índice apareceu nos planos de associados/retirados, mas **não mostrou ganho consistente que justifique recomendá-lo por estes dados**. Isso não demonstra que seja inútil em todas as distribuições de histórico.
O índice de revisão ocupou **14 401 536 bytes (13,73 MiB)**; o segundo acrescentou **17 580 032 bytes (16,77 MiB)**. O par totalizou cerca de **30,50 MiB**. Na primeira condição, criação + `ANALYZE` demoraram cerca de 1,02 s para revisão e 1,84 s para o par. Não são tempos de implantação real nem incluem criação concorrente, carga de escrita ou recuperação.
Para um futuro plano de implantação, o índice de revisão sozinho é o candidato mais parcimonioso a aprofundar. **Não foi aplicado no destino**. Todos os índices desta prova foram criados em savepoints na base sintética e desfeitos por rollback.
## Testes e preservação
- **21 testes / 322 asserções** afectados, aprovados. O novo caso verifica a ordem das referências, deduplicação, ausência do corpo/alias interno na resposta e recusa de confirmação após alteração apenas do conteúdo de uma dependência. Os casos anteriores continuam a verificar permissões, isolamento, versões, concorrência e recuperação.
- **1 ensaio / 25 499 asserções**: 44 cenários, **132 pedidos medidos completos**, sem limites atingidos; respostas completas idênticas entre as quatro variantes em cada perfil. As descrições marcadas da fixture não aparecem na resposta administrativa.
- Impressões digitais das oito tabelas antecedentes e catálogo de índices iguais antes das fixtures/depois do rollback. As sequências não foram repostas. As fixtures do ensaio de 132 pedidos foram desfeitas por rollback, preservando o estado que já existia na base de provas.
[Medições finais](proofs/module-association-projection-fanout-20261102.json) · [resumo, hashes e testes](proofs/module-association-projection-summary-20261102.json) · [diagnóstico inicial que revelou o custo de memória](proofs/module-association-fanout-20261102.json).
O código, os testes afectados e o novo ensaio são locais. Os seis registos protegidos, a cache bloqueada, as alterações alheias e as demonstrações permanecem intactos. Não houve ligação à instalação local/8039, decisão real, concessão pública, publicação, activação de Compras ou novo checkpoint.
## Limitações e repetição
Não se declara validada a capacidade de implantação: não foram medidos utilizadores simultâneos, percentis de cauda, saturação, custo de escrita, implantação/recuperação de índices ou todas as distribuições multi-módulo. Os textos são repetitivos e sintéticos, abaixo do limite de 2 000 caracteres por descrição; não representam todos os payloads. A memória reportada não é a memória PostgreSQL nem uma estimativa por utilizador concorrente.
A resposta e o número de dependências cresceram: 100 rascunhos podem apresentar mais de 10 000 nós. Não se mediu o custo de renderização desse volume no navegador. **Revisão visual permanece separada**, sem tentativa pela via bloqueada.
O launcher fixado aceita `scripts/module-association-compare.mjs fanout`, depois do `sync` da cópia de regressão existente. Requer a fonte anterior e o respectivo hash preservados no directório privado da execução, cuja integridade verifica; não substitui automaticamente essa referência. Não executar `prepare`, reset ou testes na demonstração persistente. Não existe instrução de aplicar índices ao destino. A aceitação deste incremento e um checkpoint continuam a depender de decisão expressa.