From 0cfd448bab80284ca83c1c764f8e2e13f56704ae Mon Sep 17 00:00:00 2001 From: Xu Zimo Date: Thu, 26 Feb 2026 23:55:01 +0800 Subject: [PATCH] fix(delivery-queue): change break to continue to prevent head-of-line blocking When an entry's backoff exceeds the recovery budget, the code was using break which blocked all subsequent entries from being processed. This caused permanent queue blockage for any installation with a delivery entry at retryCount >= 2. Fix: Changed break to continue so entries whose backoff exceeds the remaining budget are skipped individually rather than blocking the entire loop. Closes #27638 --- src/infra/outbound/delivery-queue.ts | 8 ++++---- src/infra/outbound/outbound.test.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/infra/outbound/delivery-queue.ts b/src/infra/outbound/delivery-queue.ts index 699ba6f7403..bd195d94a46 100644 --- a/src/infra/outbound/delivery-queue.ts +++ b/src/infra/outbound/delivery-queue.ts @@ -253,11 +253,11 @@ export async function recoverPendingDeliveries(opts: { const backoff = computeBackoffMs(entry.retryCount + 1); if (backoff > 0) { if (now + backoff >= deadline) { - const deferred = pending.length - recovered - failed - skipped; - opts.log.warn( - `Recovery time budget exceeded — ${deferred} entries deferred to next restart`, + opts.log.info( + `Backoff ${backoff}ms exceeds budget for ${entry.id} — skipping to next entry`, ); - break; + skipped += 1; + continue; } opts.log.info(`Waiting ${backoff}ms before retrying delivery ${entry.id}`); await delayFn(backoff); diff --git a/src/infra/outbound/outbound.test.ts b/src/infra/outbound/outbound.test.ts index 64960ec143c..7793f070748 100644 --- a/src/infra/outbound/outbound.test.ts +++ b/src/infra/outbound/outbound.test.ts @@ -394,12 +394,12 @@ describe("delivery-queue", () => { expect(deliver).not.toHaveBeenCalled(); expect(delay).not.toHaveBeenCalled(); - expect(result).toEqual({ recovered: 0, failed: 0, skipped: 0 }); + expect(result).toEqual({ recovered: 0, failed: 0, skipped: 1 }); const remaining = await loadPendingDeliveries(tmpDir); expect(remaining).toHaveLength(1); - expect(log.warn).toHaveBeenCalledWith(expect.stringContaining("deferred to next restart")); + expect(log.info).toHaveBeenCalledWith(expect.stringContaining("Backoff")); }); it("returns zeros when queue is empty", async () => {