Merge pull request #96 from pikasTech/code-queue/issue-20-runner-429-backoff

fix: add Code Queue 429 backoff diagnostics
This commit is contained in:
Lyon
2026-05-23 15:59:37 +08:00
committed by GitHub
6 changed files with 175 additions and 15 deletions
+9 -2
View File
@@ -12,6 +12,7 @@ export type ProviderSignalScope =
| "registry"
| "k3s"
| "scheduler"
| "external-provider"
| "service-proxy"
| "microservice"
| "unknown";
@@ -21,6 +22,7 @@ export type ProviderSignalStatus = "ok" | "degraded" | "failed" | "unknown";
export type ProviderBlockingDisposition =
| "transient"
| "runner-local-observation-gap"
| "external-provider-backoff"
| "provider-degraded"
| "service-degraded"
| "global-blocker";
@@ -280,6 +282,7 @@ function codeQueueTasksSignal(response: unknown): ProviderTriageSignal {
function classifyErrorMessage(message: string): ProviderSignalScope {
const runnerClassification = classifyRunnerError(message);
if (runnerClassification.scope === "external-provider") return "external-provider";
if (runnerClassification.scope === "provider-gateway") return "provider-gateway";
if (runnerClassification.scope === "registry") return "registry";
if (runnerClassification.scope === "k3s") return "k3s";
@@ -460,12 +463,16 @@ export function classifyProviderTriage(providerId: string, signals: ProviderTria
const independentDegradedScopes = uniqueScopes(signals, ["degraded"]);
const failedCriticalScopes = independentFailedScopes.filter((scope) => criticalScopes.has(scope));
const runnerLocalObservedFailure = signals.some((signal) => signal.scope === "runner-local" && signal.status === "failed");
const serviceOnlyFailure = independentFailedScopes.length > 0 && independentFailedScopes.every((scope) => scope === "registry" || scope === "service-proxy" || scope === "microservice" || scope === "k3s");
const externalProviderObservedFailure = signals.some((signal) => signal.scope === "external-provider" && signal.status === "failed");
const serviceOnlyFailure = independentFailedScopes.length > 0 && independentFailedScopes.every((scope) => scope === "registry" || scope === "service-proxy" || scope === "microservice" || scope === "k3s" || scope === "external-provider");
const hasIndependentHealthy = healthyScopes.length > 0;
const rationale: string[] = [];
let blockingDisposition: ProviderBlockingDisposition;
if (runnerLocalObservedFailure && independentFailedScopes.length === 0) {
if (externalProviderObservedFailure && failedCriticalScopes.length === 0) {
blockingDisposition = "external-provider-backoff";
rationale.push("external model provider 429/rate-limit should stay in Code Queue retry_wait with conservative backoff while scheduler heartbeat remains healthy");
} else if (runnerLocalObservedFailure && independentFailedScopes.length === 0) {
blockingDisposition = "runner-local-observation-gap";
rationale.push("single runner-local provider offline observation is not sufficient evidence for global D601 outage");
} else if (failedCriticalScopes.length >= 2 && healthyScopes.length === 0) {