fix(server): preserve backlog deadlines after partial failure

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-25 02:11:08 -05:00
1 parent fe1c886a3d
commit d3187f76a4
7 files changed
+126 -6

No files matched your search

@@ -860,6 +860,27 @@ suite("Discord command ownership store (real PostgreSQL, no network)", () => {
expect(errors).toEqual([]);
});
it("drains healthy commands promptly while one entry remains in failure backoff", async () => {
await reconcileDatabaseWork(db, DELIVERY_QUEUES.chatCommandRegistration);
vi.useFakeTimers({ toFake: ["Date", "setTimeout", "clearTimeout"], shouldAdvanceTime: true });
const entries = Array.from({ length: 300 }, (_, index) => ({
id: `command-${index}`, companyId: `company-${index % 10}`, connectionId: `connection-${index}`, dueAt: 0,
}));
const check = vi.fn(async (id: string) => {
if (id === "command-0") throw new Error("Unavailable credential");
return { ...entries.find(entry => entry.id === id)!, dueAt: Date.now() + 300_000 };
});
const onError = vi.fn();
coordinator = createDeliveryWorkCoordinator({ owner: db, canRun: () => true, onError });
await registerDiscordCommandWork(coordinator, { load: async () => entries, check }, () => true).ready;
await vi.advanceTimersByTimeAsync(15_000);
expect(new Set(check.mock.calls.map(([id]) => id)).size).toBe(300);
expect(check.mock.calls.filter(([id]) => id === "command-0")).toHaveLength(1);
expect(onError).toHaveBeenCalledOnce();
await vi.advanceTimersByTimeAsync(45_000);
expect(check.mock.calls.filter(([id]) => id === "command-0")).toHaveLength(2);
expect(check.mock.calls.filter(([id]) => id !== "command-0")).toHaveLength(299);
});
it("recovers queued scopes after an unknown hint instead of dropping the wake", async () => {
await reconcileDatabaseWork(db, DELIVERY_QUEUES.chatCommandRegistration);
vi.useFakeTimers({ toFake: ["Date", "setTimeout", "clearTimeout"], shouldAdvanceTime: true });
@@ -78,9 +78,16 @@ export function createDeliveryWorkCoordinator(input: {
}
}).catch(error => {
schedule(task.retryMs);
let failure = error;
try {
const next = input.canRun() ? task.nextRunAt?.() : null;
if (next != null && next > Date.now()) schedule(0, next);
} catch (deadlineError) {
failure = new AggregateError([error, deadlineError], "Delivery failure deadline could not be read");
}
// Logging must never turn a recoverable sweep failure into an
// unhandled rejection or prevent other queues from running.
try { if (!workerStopped) input.onError(error, queue); } catch { /* Recovery remains scheduled. */ }
try { if (!workerStopped) input.onError(failure, queue); } catch { /* Recovery remains scheduled. */ }
}).finally(() => {
running = null;
controller = null;