fix: 将调度重试归为基础设施进展
This commit is contained in:
@@ -976,7 +976,7 @@ function hasNoBusinessProgress(run: RunRecord, command: CommandRecord, commands:
|
||||
if (isoMs(run.createdAt) > cutoff || isoMs(command.createdAt) > cutoff) return false;
|
||||
if (commands.length !== 1 || commands[0]?.id !== command.id) return false;
|
||||
if (events.length === 0 || events.length >= 500) return false;
|
||||
const allowedPhases = new Set(["run-created", "command-created", "runner-job-created", "runner-dispatch-completed"]);
|
||||
const allowedPhases = new Set(["run-created", "command-created", "runner-dispatch-retry", "runner-job-created", "runner-dispatch-completed"]);
|
||||
const userMessages = events.filter((event) => event.type === "user_message");
|
||||
if (userMessages.length > 1) return false;
|
||||
const phases = events.flatMap((event) => {
|
||||
|
||||
@@ -120,6 +120,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
try {
|
||||
await assertTwentyStalePendingSelectsOnlyOldest({ fixturePath, statePath, kubectlCommand });
|
||||
await assertLegacyNoUserMessageCandidate({ fixturePath, statePath, kubectlCommand });
|
||||
await assertDispatchRetryIsInfrastructureProgress({ fixturePath, statePath, kubectlCommand });
|
||||
await assertEventOnlyFailedMountCandidate({ fixturePath, statePath, kubectlCommand });
|
||||
await assertTerminalClaimDriftCandidate({ fixturePath, statePath, kubectlCommand });
|
||||
await assertTerminalCommandClaimDriftCandidate({ fixturePath, statePath, kubectlCommand });
|
||||
@@ -155,6 +156,7 @@ const selfTest: SelfTestCase = async (context) => {
|
||||
"stale-pending-typed-candidate",
|
||||
"formal-user-message-is-not-runner-progress",
|
||||
"legacy-no-user-message-candidate",
|
||||
"dispatch-retry-is-not-business-progress",
|
||||
"user-message-command-binding-protected",
|
||||
"incoming-selects-only-oldest",
|
||||
"no-incoming-does-not-delete",
|
||||
@@ -320,6 +322,26 @@ async function assertLegacyNoUserMessageCandidate(input: { fixturePath: string;
|
||||
assert.equal(firstSummary(summary, "selected").candidateKind, "stale-pending");
|
||||
}
|
||||
|
||||
async function assertDispatchRetryIsInfrastructureProgress(input: { fixturePath: string; statePath: string; kubectlCommand: string }): Promise<void> {
|
||||
const fact = pendingFact(108, new Date(Date.now() - 60 * 60_000).toISOString());
|
||||
fact.events.splice(3, 0, runEvent(fact.run.id, 4, fact.run.createdAt, "backend_status", {
|
||||
phase: "runner-dispatch-retry",
|
||||
commandId: fact.command.id,
|
||||
reason: "runner retention retry self-test",
|
||||
valuesPrinted: false,
|
||||
}));
|
||||
fact.events = fact.events.map((event, index) => ({ ...event, id: `evt-${fact.run.id}-${index + 1}`, seq: index + 1 }));
|
||||
await writeFixture(input, {
|
||||
jobs: [runnerJob(fact, 108)],
|
||||
pods: [runnerPod(fact, 108, "failed-config")],
|
||||
});
|
||||
const summary = await enforceRunnerRetentionBeforeCreate({ store: new RetentionFactStore([fact]), options: retentionOptions(input.kubectlCommand, 1), incomingRunnerCount: 0 });
|
||||
assert.equal(summary.inactiveCandidateCount, 1);
|
||||
const candidate = firstSummary(summary, "inactiveCandidates");
|
||||
assert.equal(candidate.candidateKind, "stale-pending");
|
||||
assert.equal(candidate.classificationReason, "stale-pending-no-business-progress");
|
||||
}
|
||||
|
||||
async function assertEventOnlyFailedMountCandidate(input: { fixturePath: string; statePath: string; kubectlCommand: string }): Promise<void> {
|
||||
const fact = pendingFact(90, new Date(Date.now() - 60 * 60_000).toISOString());
|
||||
const fixture = {
|
||||
|
||||
Reference in New Issue
Block a user