fix ssh tcp pool transient diagnostics

This commit is contained in:
Codex
2026-06-13 17:19:08 +00:00
parent 1ec60de8bb
commit 2cf767b635
7 changed files with 285 additions and 5 deletions
+45
View File
@@ -38,6 +38,7 @@ export interface JobProgressSummary {
eventsObserved: number;
slow: boolean;
warnings: string[];
diagnostics?: Record<string, unknown> | null;
timings: Record<string, number>;
summary: string;
nextCommand: string | null;
@@ -437,6 +438,7 @@ function summarizeRuntimeLaneTriggerJobProgress(job: JobRecord, stdoutTail: stri
stageElapsedSeconds,
lastEventAgeSeconds,
});
const tcpPoolDiagnostics = job.status === "succeeded" ? null : sshTcpPoolDiagnosticsFromJobText(`${stderrTail}\n${stdoutTail}`);
const slow = warnings.length > 0;
return {
kind: "hwlab-runtime-lane-trigger",
@@ -452,6 +454,7 @@ function summarizeRuntimeLaneTriggerJobProgress(job: JobRecord, stdoutTail: stri
eventsObserved: events.length,
slow,
warnings,
diagnostics: tcpPoolDiagnostics,
timings,
summary: [
job.status,
@@ -462,6 +465,7 @@ function summarizeRuntimeLaneTriggerJobProgress(job: JobRecord, stdoutTail: stri
elapsedSeconds !== null ? `elapsed=${elapsedSeconds}s` : null,
stageElapsedSeconds !== null && job.status === "running" ? `stageElapsed=${stageElapsedSeconds}s` : null,
lastEventAgeSeconds !== null && job.status === "running" ? `lastEventAge=${lastEventAgeSeconds}s` : null,
tcpPoolDiagnostics !== null ? `sshPool=${String(tcpPoolDiagnostics.failureKind ?? "transient")}` : null,
slow ? "visibility-warning" : null,
].filter(Boolean).join(" "),
nextCommand: pipelineRun
@@ -472,6 +476,47 @@ function summarizeRuntimeLaneTriggerJobProgress(job: JobRecord, stdoutTail: stri
};
}
function sshTcpPoolDiagnosticsFromJobText(text: string): Record<string, unknown> | null {
const hint = lastJsonLinePayload(text, "UNIDESK_SSH_TCP_POOL_HINT");
if (hint !== null) return hint;
const error = lastJsonLinePayload(text, "UNIDESK_SSH_ERROR");
if (error !== null && typeof error.failureKind === "string" && error.failureKind.startsWith("provider-data-")) {
return {
code: "ssh-tcp-pool-transient",
failureKind: error.failureKind,
providerId: error.providerId ?? null,
dataChannelId: error.dataChannelId ?? null,
dataPool: error.dataPool ?? null,
diagnostics: { fullHealth: "bun scripts/cli.ts debug health" },
};
}
if (/ssh tcp data channel closed/iu.test(text)) {
return { code: "ssh-tcp-pool-transient", failureKind: "provider-data-channel-closed", diagnostics: { fullHealth: "bun scripts/cli.ts debug health" } };
}
if (/requested ssh tcp data channel is not ready|ssh tcp data channel is not available/iu.test(text)) {
return { code: "ssh-tcp-pool-transient", failureKind: "provider-data-channel-missing", diagnostics: { fullHealth: "bun scripts/cli.ts debug health" } };
}
if (/provider ssh tcp data pool has no idle channel/iu.test(text)) {
return { code: "ssh-tcp-pool-transient", failureKind: "provider-data-pool-exhausted", diagnostics: { fullHealth: "bun scripts/cli.ts debug health" } };
}
return null;
}
function lastJsonLinePayload(text: string, prefix: string): Record<string, unknown> | null {
const lines = text.split(/\r?\n/u);
for (let index = lines.length - 1; index >= 0; index -= 1) {
const line = lines[index]?.trim() ?? "";
if (!line.startsWith(`${prefix} `)) continue;
try {
const parsed = JSON.parse(line.slice(prefix.length + 1)) as unknown;
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed as Record<string, unknown>;
} catch {
return null;
}
}
return null;
}
function genericJobProgress(job: JobRecord, stderrTailOverride?: string): JobProgressSummary {
const nowMs = Date.now();
const stderrTail = stderrTailOverride ?? tailFile(job.stderrFile, 96_000);