fix(server): retain idle hold for uncertain delivery commits

Keep an ambiguous database write visible to sleep admission between recovery attempts. Release the hold only when the worker stops.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-08 15:03:36 -05:00
1 parent 46a1e4a434
commit b9ee041655
3 files changed
+13 -3

No files matched your search

@@ -201,8 +201,8 @@ acknowledgement fails, the worker conservatively keeps recovery checks active
until the process restarts. Neither an empty read nor delivery of an unrelated
record can prove that an ambiguous commit will not appear later. An autocommit receipt
write that fails uses the same conservative recovery mode. This exceptional
path can keep an otherwise empty queue awake; it deliberately favors delivery
recovery. Normal successful transactions have no empty-queue backstop.
path also holds idle admission, so an empty durable scan cannot authorize sleep
while the commit outcome is unknown. It deliberately favors delivery recovery. Normal successful transactions have no empty-queue backstop.
The supported writer boundary is one server process using its `createDb`
instance and the instrumented service mutations. Startup recovers durable rows
@@ -46,12 +46,16 @@ describe("delivery queue workers", () => {
const s = setup();
await s.worker.ready;
signalDatabaseWork(s.db, s.topic, true);
expect(idleWorkSnapshot().active).toBe(1);
await vi.advanceTimersByTimeAsync(3000);
expect(s.run.mock.calls.length).toBeGreaterThan(3);
expect(vi.getTimerCount()).toBe(1);
s.hasPending.mockResolvedValueOnce(true);
await vi.advanceTimersByTimeAsync(2000);
expect(vi.getTimerCount()).toBe(1);
expect(idleWorkSnapshot().active).toBe(1);
await s.worker.stop();
expect(idleWorkSnapshot().active).toBe(0);
});
it("does not lose a commit racing the final empty check or overlap deliveries", async () => {
+7 -1
View File
@@ -26,6 +26,7 @@ export function createDeliveryQueueWorker(input: {
let stopped = false;
let dirty = false;
let uncertainCommit = false;
let finishUncertainCommit: (() => void) | null = null;
let running: Promise<void> | null = null;
let timer: ReturnType<typeof setTimeout> | null = null;
@@ -67,7 +68,10 @@ export function createDeliveryQueueWorker(input: {
// A lost COMMIT acknowledgement can precede visibility on another
// connection. Even observing other pending work cannot resolve that
// ambiguity. Retain a conservative recovery backstop until restart.
uncertainCommit ||= uncertain;
if (uncertain && !uncertainCommit) {
uncertainCommit = true;
finishUncertainCommit = beginIdleTrackedWork();
}
dirty = true;
if (!running) arm(0);
}
@@ -83,6 +87,8 @@ export function createDeliveryQueueWorker(input: {
if (timer) clearTimeout(timer);
timer = null;
await running;
finishUncertainCommit?.();
finishUncertainCommit = null;
},
};
}