Feat/durable webhook queue - #182
Open
samuel22x wants to merge 5 commits into
Open
Conversation
Replace in-process retry with a DB-backed webhook_queue table so a crash mid-backoff no longer loses pending deliveries. - Add webhook_queue table: id, webhook_id, link_id, event, payload, attempts, next_attempt_at, status (pending/claimed/delivered/dead), last_status_code, last_error, created_at, updated_at. Add idx_webhook_queue_due index on (status, next_attempt_at). - Extend webhook_deliveries with attempt (1-based) and queue_entry_id so every individual attempt is queryable, not just the final outcome. - Extend WebhookRepository port: enqueue, claimDue, updateQueueEntry, findQueueEntry, findWebhookById. - WebhookSender.dispatch now writes queue rows and returns immediately; event emission never blocks a state transition. - New WebhookWorker polling delivery loop: claims due rows with an optimistic-lock UPDATE (prevents double-send across concurrent instances), delivers signed frozen payload, reschedules with exponential backoff + full jitter, dead-letters after N attempts. Records a webhook_deliveries row per attempt. - Wire WebhookWorker into container start()/stop(). - POST /webhooks/deliveries/:id/replay resets dead/failed entries to pending for immediate redelivery; 409 if entry is in-flight. - Signing scheme and headers (X-Checkout-Signature, X-Checkout-Event) identical to old sender — receivers need no changes. - Update docs/API.md; create ISSUES.md tracking entry.
An 87-line ISSUES.md unrelated to the webhook queue was committed on this branch. The repository does not track ISSUES.md — the maintainer keeps a much larger one locally — so this file only shadows theirs on checkout.
claimDue() transitioned pending -> claimed with a conditional UPDATE, then re-SELECTed rows WHERE status='claimed'. That second query also matches rows a concurrent worker claimed between our UPDATE and our SELECT, so two instances could both return — and deliver — the same webhook. Issue 4.2 item 3 requires the opposite. Taking the rows off the UPDATE with RETURNING yields exactly the rows this statement transitioned, with no window in between.
The branch was 105 commits behind. Six conflicts resolved; the substantive one
is webhook-sender.ts, where this branch turns the sender into an enqueuer while
main had grown in-process retry, metrics and an inFlightCount getter.
Carried across from main rather than dropped:
- webhookQueueDepth() fed off sender.inFlightCount, which no longer exists.
Repointed at a pending counter on the sender, which is what the
webhook_deliveries_in_flight gauge was always meant to measure.
- WebhookDelivery gained attempt and queueEntryId; queueEntryId is nullable to
match the column ('null for legacy rows') and listDeliveriesByLinkId now maps
both. recordDelivery calls carry createdAt.
- Five test fakes gained findWebhookById / enqueue / claimDue /
updateQueueEntry / findQueueEntry.
Also on this branch: the stray 87-line ISSUES.md is removed (573a832) and the
queue claim is made genuinely atomic with RETURNING (3d679f4).
CI is red and deliberately left that way: 20 pre-existing tests now fail
because the behaviour they assert moved to WebhookWorker. See the review.
|
@determined-001 is attempting to deploy a commit to the determined's projects Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Describe what this PR changes.
Why
The motivation / problem being solved. Link any related issue (e.g.
Closes #8.7).How
Brief notes on the approach. If it touches a chain or anchor, confirm the change
stays behind a port and the domain (
packages/core) imports no chain SDK.Checklist
pnpm typecheckpassespnpm testpassespnpm buildpassesseller_initiatedtoinlineBug fix? (skip if not a bug fix)
docs/FIXLOG.md(date · symptom · root cause · fix commit · test name)scloses #22