Skip to content

Commit e12a356

Browse files
committed
fix(admin): keep webhook timeouts notify-only
The released drain contract advances the cursor on failed posts so subscribers are not retried. Timeout now matches HTTP and unreachable: advance, record timeout, stop the batch. That avoids duplicating a post that completed after the cutoff. Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
1 parent 63f6c5e commit e12a356

2 files changed

Lines changed: 5 additions & 5 deletions

File tree

‎apps/api/src/admin/webhooks.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,9 @@ export async function deleteWebhook(
118118

119119
/** POST change-log entries newer than each enabled webhook's cursor.
120120
* Runs off the request path (waitUntil) after every admin mutation.
121-
* Delivery is notify-only for HTTP and network failures: the cursor
122-
* advances so a dead subscriber cannot stall the queue. A timeout does
123-
* not advance the cursor, so a slow subscriber is retried on the next
124-
* drain instead of permanently skipping the batch. */
121+
* Delivery is notify-only: HTTP, network, and timeout failures all
122+
* advance the cursor so a dead or slow subscriber cannot stall the
123+
* queue or duplicate a post that already completed after cutoff. */
125124
export async function drainWebhooks(
126125
db: DrizzleD1Database,
127126
fetcher: typeof fetch = fetch,
@@ -188,6 +187,7 @@ async function drainOneWebhook(
188187
} catch (error) {
189188
if (isFetchTimeout(error)) {
190189
status = "timeout";
190+
cursor = rowid;
191191
break;
192192
}
193193
status = "unreachable";

‎apps/api/test/webhooks.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ describe("drainWebhooks", () => {
194194
await drainWebhooks(db, countingFetch, 20);
195195
expect(
196196
retried.filter((url) => url.startsWith("https://hang.example/")),
197-
).toHaveLength(1);
197+
).toHaveLength(0);
198198

199199
await SELF.fetch(`${BASE}/admin/webhooks/${id}`, {
200200
method: "DELETE",

0 commit comments

Comments
 (0)