mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 12:22:34 +03:00
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`.
26 lines
1.1 KiB
TypeScript
26 lines
1.1 KiB
TypeScript
import { isLocalStreamLifecycleError } from "@/shared/utils/circuitBreaker.ts";
|
|
import {
|
|
markLocalRateLimitError,
|
|
LEGACY_RATE_LIMIT_QUEUE_TIMEOUT_CODE,
|
|
} from "../../services/rateLimitManager/errors.ts";
|
|
|
|
/**
|
|
* Rethrow a hierarchical-admission failure. Aborts, stream-lifecycle errors and coded
|
|
* semaphore errors pass through unchanged (SEMAPHORE_QUEUE_FULL is a 429 admission signal
|
|
* the combo cascade reads); only a bare time-budget timeout becomes the LEGACY queue 503.
|
|
*/
|
|
export function rethrowAdmissionError(error: unknown): never {
|
|
const err = error as { name?: unknown; code?: unknown } | null;
|
|
if (err?.name === "AbortError" || err?.code === "ABORT_ERR") throw error;
|
|
if (isLocalStreamLifecycleError(error)) throw error;
|
|
if (err?.code === undefined) {
|
|
throw markLocalRateLimitError(error as Error, LEGACY_RATE_LIMIT_QUEUE_TIMEOUT_CODE);
|
|
}
|
|
throw error;
|
|
}
|
|
|
|
/** What is left of a queue-wait budget that started at `startedAt`. */
|
|
export function remainingQueueBudgetMs(budgetMs: number, startedAt: number): number {
|
|
return Math.max(0, budgetMs - (Date.now() - startedAt));
|
|
}
|