perf(sincronizacao): remover os tetos que travavam a base em mil empr… - #30
Merged
Merged
Conversation
…esas Quatro gargalos medidos contra o ambiente real, onde uma execução leva cerca de nove segundos por consulta à SEFAZ e o ciclo de trinta minutos enfileira quinhentas empresas. Capacidade do ciclo deixa de ser constante `EmpresasPorCiclo` e `Workers` eram constantes privadas, e a base parava de crescer em mil empresas sem que nada avisasse. Empresa sem novidade volta em uma hora, então metade da base fica elegível a cada ciclo: quinhentas por ciclo atendem mil empresas, e o excedente escorrega para o ciclo seguinte em silêncio. A validação recusa no boot. Agendador com zero worker sobe calado e não processa nada — a fila enche, os documentos não chegam, e nada no sistema explica por quê. Certificado deixa de ser recarregado a cada lote Drenar uma empresa atrasada encadeia até vinte consultas à SEFAZ, duzentas na carga inicial, e cada uma pedia o mesmo certificado de volta ao object storage para decifrá-lo com AES-GCM e derivá-lo com PBKDF2 outra vez, produzindo exatamente o mesmo material. O cache tem escopo de execução, não de processo: o registro é `Scoped` e cada trabalho do Hangfire abre o próprio escopo. A chave privada continua sem persistir entre execuções e sem atravessar empresas; o descarte zera os bytes decifrados. Remover um certificado invalida o que estava em memória — continuar servindo a cópia entregaria o que o operador mandou apagar. Uma consulta no lugar de cinquenta A SEFAZ entrega até cinquenta documentos por chamada, e o laço perguntava ao banco por um de cada vez: mil consultas numa execução que encadeia vinte lotes. A comparação é sobre o objeto de valor, não sobre o texto dentro dele. A chave é mapeada por conversor e o provedor enxerga uma coluna só, então `Chave.Valor` não é membro que ele saiba traduzir — comparando o objeto, o conversor entra e a condição vira um `IN`. Índices com a forma da pergunta O filtro do contador vira `EXISTS (SELECT 1 FROM itens WHERE documento_fiscal_id = ? AND cfop LIKE ?)`, e os índices eram só pelo código. A consulta parte da grade, já estreitada por empresa e período, e sonda os itens de cada documento; indexar apenas o código obrigaria o banco a percorrer todas as linhas com aquele CFOP no acervo inteiro para depois cruzar. Os antigos foram removidos, e não somados: a tabela cresce por item, não por nota, e chega a dezenas de milhões de linhas no primeiro ano. Índice que nenhuma consulta usa custa escrita e espaço em cada uma delas.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…esas
Quatro gargalos medidos contra o ambiente real, onde uma execução leva cerca de nove segundos por consulta à SEFAZ e o ciclo de trinta minutos enfileira quinhentas empresas.
Capacidade do ciclo deixa de ser constante
EmpresasPorCicloeWorkerseram constantes privadas, e a base parava de crescer em mil empresas sem que nada avisasse. Empresa sem novidade volta em uma hora, então metade da base fica elegível a cada ciclo: quinhentas por ciclo atendem mil empresas, e o excedente escorrega para o ciclo seguinte em silêncio.A validação recusa no boot. Agendador com zero worker sobe calado e não processa nada — a fila enche, os documentos não chegam, e nada no sistema explica por quê.
Certificado deixa de ser recarregado a cada lote
Drenar uma empresa atrasada encadeia até vinte consultas à SEFAZ, duzentas na carga inicial, e cada uma pedia o mesmo certificado de volta ao object storage para decifrá-lo com AES-GCM e derivá-lo com PBKDF2 outra vez, produzindo exatamente o mesmo material.
O cache tem escopo de execução, não de processo: o registro é
Scopede cada trabalho do Hangfire abre o próprio escopo. A chave privada continua sem persistir entre execuções e sem atravessar empresas; o descarte zera os bytes decifrados. Remover um certificado invalida o que estava em memória — continuar servindo a cópia entregaria o que o operador mandou apagar.Uma consulta no lugar de cinquenta
A SEFAZ entrega até cinquenta documentos por chamada, e o laço perguntava ao banco por um de cada vez: mil consultas numa execução que encadeia vinte lotes.
A comparação é sobre o objeto de valor, não sobre o texto dentro dele. A chave é mapeada por conversor e o provedor enxerga uma coluna só, então
Chave.Valornão é membro que ele saiba traduzir — comparando o objeto, o conversor entra e a condição vira umIN.Índices com a forma da pergunta
O filtro do contador vira
EXISTS (SELECT 1 FROM itens WHERE documento_fiscal_id = ? AND cfop LIKE ?), e os índices eram só pelo código. A consulta parte da grade, já estreitada por empresa e período, e sonda os itens de cada documento; indexar apenas o código obrigaria o banco a percorrer todas as linhas com aquele CFOP no acervo inteiro para depois cruzar.Os antigos foram removidos, e não somados: a tabela cresce por item, não por nota, e chega a dezenas de milhões de linhas no primeiro ano. Índice que nenhuma consulta usa custa escrita e espaço em cada uma delas.