fix(resilience): stop unbounded queue that hangs 6min until Aborted (#12715)

Fila sem teto que segura a request seis minutos até o cliente abortar é pior que 503 imediato: consome slot, mascara a saturação e ainda entrega erro no fim. Um orçamento `maxWaitMs` por conexão compartilhado entre gate, slot padrão do provider e fila do Bottleneck é a forma certa — o teto tem que ser um só, senão cada camada espera o seu.

O `max(perConn, upstream)` no `executionMaxWaitMs` é o detalhe que evita a correção matar request em voo, que seria trocar um defeito por outro.

Registro a atribuição: você manteve o #12635 aberto para o @Tushar49 e creditou a percepção dele (providers lentos precisam de 2min→10min por conexão) enquanto adiciona o encanamento que faltava. É o jeito certo de construir sobre PR de outra pessoa sem tomar o crédito.

Sobre o `npm run lint` desmarcado com a nota do eslint quebrado no ambiente: deixar em branco e explicar vale mais que marcar sem ter rodado. Rodei aqui: limpo.

Revalidei sobre o tip: **13/13**, typecheck:core limpo, check-file-size OK. O `file-size-baseline.json` conflitou com os rebaselines desta campanha — resolvido aditivamente, JSON revalidado com `json.load`.
This commit is contained in:
Dizzle
2026-09-10 15:49:34 +02:00
committed by GitHub
parent d6a61074dc
commit a152eb92db
11 changed files with 643 additions and 25 deletions

View File

@@ -28,6 +28,8 @@ export interface RequestQueueSettings {
* only after a job leaves QUEUED). Kept separate from `maxWaitMs` because
* non-incremental gateways legitimately take minutes before first bytes;
* the backstop must never undercut the upstream fetch-start timeout.
* Per-connection `rateLimitOverrides.executionMaxWaitMs` can override this
* global default (bounded 0..600000 via provider schema; 0 falls through).
*/
executionMaxWaitMs: number;
/**

View File

@@ -560,6 +560,7 @@ export const updateProviderConnectionSchema = z
minTime: rateLimitOverrideNumber(60_000).optional(),
maxConcurrent: rateLimitOverrideNumber(10_000).optional(),
maxWaitMs: rateLimitOverrideNumber(120_000).optional(),
executionMaxWaitMs: rateLimitOverrideNumber(600_000).optional(),
})
.partial()
.strict()