Skip to content

feat(infra): nova tentativa no object storage para não queimar cota d… - #29

Merged
net0well merged 1 commit into
mainfrom
feature/019-resiliencia-storage
Jul 29, 2026
Merged

net0well merged 1 commit into
mainfrom
feature/019-resiliencia-storage

Conversation

@net0well

Copy link
Copy Markdown
Owner

…a SEFAZ

Falha ao arquivar aborta o lote inteiro, o ponteiro de NSU não avança, e a rodada seguinte busca os mesmos documentos na SEFAZ de novo. A consulta é o recurso racionado; a gravação no MinIO não custa nada. Um soluço de rede de meio segundo custava uma ida à SEFAZ.

O pipeline repete até três vezes, com espera exponencial e jitter, e limita cada tentativa em 30 segundos. O jitter importa porque a sincronização roda em paralelo por empresa: sem ele, as que falharem juntas voltariam juntas e a segunda tentativa recriaria a rajada.

Sem disjuntor, de propósito. Ele seria por processo e em memória, enquanto o que precisa ser contido já é contido no lugar certo: o bloqueio por empresa vive no banco, sobrevive a reinício e vale para todas as instâncias. Um disjuntor sobre "o MinIO" ainda pararia a captura de todas as empresas por causa de uma, sem nada em troca — se o storage caiu de vez, o job já falha rápido e o ciclo seguinte retoma. Pela mesma razão nada foi acrescentado à SEFAZ: 656 não é falha transitória, e repetir aprofunda o bloqueio.

Classificação por lista de permissão

Quase toda exceção do SDK herda de MinioException, inclusive ObjectNotFoundException, AccessDeniedException e InvalidBucketNameException. Um Handle genérico repetiria arquivo inexistente e credencial errada três vezes para chegar ao mesmo lugar. Repete-se apenas o que se sabe transitório; o resto é definitivo. A lista de permissão também envelhece melhor: exceção nova do SDK entra como definitiva, que é o padrão seguro.

Um stream por tentativa

O MemoryStream é criado dentro do pipeline. Reaproveitá-lo faria a segunda tentativa encontrá-lo no fim e gravar um objeto de zero byte — sem erro nenhum, porque do ponto de vista do SDK o envio deu certo, e o XML sumiria em silêncio. Repetir é seguro porque a operação é idempotente: o mesmo nome com o mesmo conteúdo produz o mesmo objeto, e o XML autorizado nunca muda.

…a SEFAZ

Falha ao arquivar aborta o lote inteiro, o ponteiro de NSU não avança, e a rodada seguinte
busca os mesmos documentos na SEFAZ de novo. A consulta é o recurso racionado; a gravação
no MinIO não custa nada. Um soluço de rede de meio segundo custava uma ida à SEFAZ.

O pipeline repete até três vezes, com espera exponencial e jitter, e limita cada tentativa
em 30 segundos. O jitter importa porque a sincronização roda em paralelo por empresa: sem
ele, as que falharem juntas voltariam juntas e a segunda tentativa recriaria a rajada.

Sem disjuntor, de propósito. Ele seria por processo e em memória, enquanto o que precisa
ser contido já é contido no lugar certo: o bloqueio por empresa vive no banco, sobrevive a
reinício e vale para todas as instâncias. Um disjuntor sobre "o MinIO" ainda pararia a
captura de todas as empresas por causa de uma, sem nada em troca — se o storage caiu de
vez, o job já falha rápido e o ciclo seguinte retoma. Pela mesma razão nada foi acrescentado
à SEFAZ: 656 não é falha transitória, e repetir aprofunda o bloqueio.

Classificação por lista de permissão

Quase toda exceção do SDK herda de MinioException, inclusive ObjectNotFoundException,
AccessDeniedException e InvalidBucketNameException. Um Handle<MinioException> genérico
repetiria arquivo inexistente e credencial errada três vezes para chegar ao mesmo lugar.
Repete-se apenas o que se sabe transitório; o resto é definitivo. A lista de permissão
também envelhece melhor: exceção nova do SDK entra como definitiva, que é o padrão seguro.

Um stream por tentativa

O MemoryStream é criado dentro do pipeline. Reaproveitá-lo faria a segunda tentativa
encontrá-lo no fim e gravar um objeto de zero byte — sem erro nenhum, porque do ponto de
vista do SDK o envio deu certo, e o XML sumiria em silêncio. Repetir é seguro porque a
operação é idempotente: o mesmo nome com o mesmo conteúdo produz o mesmo objeto, e o XML
autorizado nunca muda.
@net0well
net0well merged commit 80eb4f9 into main Jul 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant