fix(captura): grade do ciclo perdia a janela por segundos, e o filtro… - #37
Merged
Merged
Conversation
… de data derrubava a consulta
Grade do ciclo de trinta para cinco minutos
O vencimento da próxima consulta é gravado como `agora + IntervaloSemNovidade`, onde `agora` é
o instante em que a execução da empresa começou — sempre alguns segundos depois do tique do
ciclo, por causa da espera na fila e da chamada à SEFAZ, que leva perto de nove segundos.
Somando exatamente uma hora, o vencimento caía sistematicamente logo após o tique
correspondente: o ciclo das 16:30:01 não pegou empresas que venciam às 16:30:07 e 16:30:09, e
elas esperaram até as 17:00. O intervalo real oscilava entre uma hora e uma hora e meia.
Antecipar a consulta em alguns segundos para acertar o tique não serve: a SEFAZ exige no mínimo
uma hora entre consultas depois de um `cStat 137`, e `IntervaloSemNovidade` vale exatamente uma
hora por causa disso. Sair antes é o gatilho do 656.
O que muda é a granularidade da grade, não o intervalo. A elegibilidade continua sendo a mesma
cláusula, então nenhuma consulta à SEFAZ acontece mais cedo do que antes; a empresa que vence
poucos segundos depois de um tique espera cinco minutos em vez de trinta. O custo por tique é
uma consulta em índice parcial.
Métrica de ciclo vazio
O atraso máximo só enxerga quem já venceu, então o ciclo vazio media zero — inclusive quando
havia empresa vencendo segundos depois do tique. Era o ponto cego que escondia exatamente o
problema acima.
`espera_ate_a_proxima` publica quanto falta para a próxima empresa vencer, lido junto de
`empresas_elegiveis`. Zero elegíveis com espera de poucos segundos é o ciclo perdendo a janela
por pouco. A consulta extra acontece só no ciclo vazio, onde é a única informação disponível; o
caminho que enfileirou algo continua com uma consulta só.
O medidor reporta ausência de medição, e não zero, quando nada está programado: zero diria que
uma empresa está vencendo agora e mandaria investigar um ciclo perdido que não existe.
Filtro de data derrubava a consulta de documentos
`<input type="date">` devolve `2026-07-29`, sem hora e sem fuso, e o binder do ASP.NET produz
`DateTime` com `Kind=Unspecified`. O Npgsql recusa isso ao comparar com uma coluna
`timestamptz`, e a falha aparecia no meio da execução da consulta, não na validação:
Cannot write DateTime with Kind=Unspecified to PostgreSQL type
'timestamp with time zone', only UTC is supported
`FiltroDocumentos` e `ObterRelatorioPorEmpresaQuery` passam a normalizar o período para UTC no
próprio contrato, o que cobre os três endpoints afetados e qualquer chamador futuro sem repetir
conversão em cada um.
Quem resolve o dia é o navegador, porque é o único que conhece o fuso de quem está olhando a
tela: `2026-07-29` vira o intervalo entre o início e o fim daquele dia no relógio local. São
três horas de notas em cada ponta que ficariam de fora se o servidor tratasse a data como dia
UTC. O fim do dia é 23:59:59.999, e não a meia-noite seguinte, porque o filtro compara com
`<=`.
O filtro e a URL continuam guardando a data pura — é o que o campo exibe de volta e o que faz o
endereço permanecer legível e compartilhável. A conversão acontece só ao montar a requisição.
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.
… de data derrubava a consulta
Grade do ciclo de trinta para cinco minutos
O vencimento da próxima consulta é gravado como
agora + IntervaloSemNovidade, ondeagoraé o instante em que a execução da empresa começou — sempre alguns segundos depois do tique do ciclo, por causa da espera na fila e da chamada à SEFAZ, que leva perto de nove segundos. Somando exatamente uma hora, o vencimento caía sistematicamente logo após o tique correspondente: o ciclo das 16:30:01 não pegou empresas que venciam às 16:30:07 e 16:30:09, e elas esperaram até as 17:00. O intervalo real oscilava entre uma hora e uma hora e meia.Antecipar a consulta em alguns segundos para acertar o tique não serve: a SEFAZ exige no mínimo uma hora entre consultas depois de um
cStat 137, eIntervaloSemNovidadevale exatamente uma hora por causa disso. Sair antes é o gatilho do 656.O que muda é a granularidade da grade, não o intervalo. A elegibilidade continua sendo a mesma cláusula, então nenhuma consulta à SEFAZ acontece mais cedo do que antes; a empresa que vence poucos segundos depois de um tique espera cinco minutos em vez de trinta. O custo por tique é uma consulta em índice parcial.
Métrica de ciclo vazio
O atraso máximo só enxerga quem já venceu, então o ciclo vazio media zero — inclusive quando havia empresa vencendo segundos depois do tique. Era o ponto cego que escondia exatamente o problema acima.
espera_ate_a_proximapublica quanto falta para a próxima empresa vencer, lido junto deempresas_elegiveis. Zero elegíveis com espera de poucos segundos é o ciclo perdendo a janela por pouco. A consulta extra acontece só no ciclo vazio, onde é a única informação disponível; o caminho que enfileirou algo continua com uma consulta só.O medidor reporta ausência de medição, e não zero, quando nada está programado: zero diria que uma empresa está vencendo agora e mandaria investigar um ciclo perdido que não existe.
Filtro de data derrubava a consulta de documentos
<input type="date">devolve2026-07-29, sem hora e sem fuso, e o binder do ASP.NET produzDateTimecomKind=Unspecified. O Npgsql recusa isso ao comparar com uma colunatimestamptz, e a falha aparecia no meio da execução da consulta, não na validação:FiltroDocumentoseObterRelatorioPorEmpresaQuerypassam a normalizar o período para UTC no próprio contrato, o que cobre os três endpoints afetados e qualquer chamador futuro sem repetir conversão em cada um.Quem resolve o dia é o navegador, porque é o único que conhece o fuso de quem está olhando a tela:
2026-07-29vira o intervalo entre o início e o fim daquele dia no relógio local. São três horas de notas em cada ponta que ficariam de fora se o servidor tratasse a data como dia UTC. O fim do dia é 23:59:59.999, e não a meia-noite seguinte, porque o filtro compara com<=.O filtro e a URL continuam guardando a data pura — é o que o campo exibe de volta e o que faz o endereço permanecer legível e compartilhável. A conversão acontece só ao montar a requisição.