fix: honor compaction cancellation and replay identity

This commit is contained in:
2026-10-02 05:38:42 +09:00
parent 88338229a1
commit d10783c0d6
4 changed files with 47 additions and 4 deletions
+4
View File
@@ -5291,6 +5291,10 @@ impl<C: LlmClient + 'static, St: Store> Worker<C, St> {
info!(new_segment_id = %new_segment_id, "Manual compaction succeeded");
Ok(ManualCompactResult::Compacted { new_segment_id })
}
Err(WorkerError::CompactCancelled) => {
info!("Manual compaction was cancelled");
Err(WorkerError::CompactCancelled)
}
Err(e) => {
warn!(error = %e, "Manual compaction failed");
self.alert(
+5 -1
View File
@@ -1736,7 +1736,11 @@ async fn manual_compact_cancel_clears_progress_before_returning_idle() {
Event::CompactionProgress { compaction: None } => {
saw_interrupted = true;
}
Event::Error { .. } => saw_cancel_error = true,
Event::Error { .. }
| Event::Alert(protocol::Alert {
level: protocol::AlertLevel::Error,
..
}) => saw_cancel_error = true,
Event::WorkerState { snapshot }
if snapshot.catalog_status() == protocol::WorkerStatus::Idle =>
{
@@ -376,6 +376,35 @@ Deno.test("durable compaction failure reconciles live alert and error in both vi
assertEquals(merged.find((line) => line.kind === "error")?.entryId, "failed-entry");
});
Deno.test("reapplying one committed run_error entry is idempotent in both views", () => {
const committed = (eventId: string): ConsoleEventInput => ({
eventId,
event: {
event: "session_entry_committed",
data: {
entry: {
entry_id: "same-run-error",
timestamp: 10,
provenance: "legacy_unknown",
kind: "run_error",
message: "mid-run compaction failed: summary unavailable",
failure: "compaction",
},
},
},
});
const projection = projectConsole([
committed("live-delivery"),
committed("snapshot-replay"),
]);
const errors = projection.lines.filter((line) => line.kind === "error");
assertEquals(errors.length, 1);
assertEquals(errors[0].entryId, "same-run-error");
assertEquals(projectConsoleLines(projection.lines, "normal").length, 1);
assertEquals(projectConsoleLines(projection.lines, "overview").length, 1);
});
Deno.test("snapshot restores compaction terminal without reviving transition progress", () => {
const projection = projectConsole([{
eventId: "snapshot",
@@ -1287,15 +1287,19 @@ function hasDurableRunFailure(
function appendDurableRunFailure(
projection: ConsoleProjection,
eventId: string,
entryId: string | undefined,
message: string,
failure: string | undefined,
): void {
if (
entryId && projection.lines.some((line) => line.entryId === entryId)
) return;
projection.lines = projection.lines.filter((line) => {
if (isDurableRunFailure(line)) return true;
return !(line.kind === "error" && runFailureMessagesMatch(line.body, message));
});
projection.lines.push(
line(
projection.lines.push({
...line(
eventId,
"error",
failure === "compaction" ? "Compaction failed" : "Run error",
@@ -1304,7 +1308,8 @@ function appendDurableRunFailure(
false,
true,
),
);
entryId,
});
}
function appendAlertLine(
@@ -2198,6 +2203,7 @@ function applySessionEntry(
appendDurableRunFailure(
projection,
eventId,
stringField(value, "entry_id"),
stringField(value, "message") ?? "Worker run failed.",
stringField(value, "failure"),
);