fix(delivery-queue): break immediately on deadline instead of failing all remaining entries

P1-C: After now >= deadline, the old code would iterate all remaining queue
entries and call failDelivery() on each — O(n) work that nullified the
maxRecoveryMs wall-clock cap on large queues.

Fix: break out of the recovery loop immediately when the deadline is exceeded.
Remaining entries are picked up on next startup unchanged (retryCount not
incremented). The deadline means 'stop here', not 'fail everything remaining'.
This commit is contained in:
Stephen Schoettler
2026-03-01 20:13:40 -08:00
committed by Peter Steinberger
parent 4e92807f10
commit 20f758d4cb

View File

@@ -344,19 +344,7 @@ export async function recoverPendingDeliveries(opts: {
for (const entry of pending) {
const now = Date.now();
if (now >= deadline) {
// Increment retryCount on remaining entries so they eventually hit MAX_RETRIES
const remaining = pending.slice(pending.indexOf(entry));
for (const r of remaining) {
try {
await failDelivery(r.id, "Recovery time budget exceeded — deferred", opts.stateDir);
} catch {
/* best-effort */
}
}
const deferred = remaining.length;
opts.log.warn(
`Recovery time budget exceeded — ${deferred} entries deferred (retryCount incremented)`,
);
opts.log.warn(`Recovery time budget exceeded — remaining entries deferred to next startup`);
break;
}
if (entry.retryCount >= MAX_RETRIES) {