feat: dead letter queue for failed message processing (Closes #124) - #148
Open
aaronmanuel309-bot wants to merge 2 commits into
Open
feat: dead letter queue for failed message processing (Closes #124)#148aaronmanuel309-bot wants to merge 2 commits into
aaronmanuel309-bot wants to merge 2 commits into
Conversation
Permanently failed deliveries (max retries exhausted) and SSRF-blocked jobs are now routed to a bounded dead letter queue instead of being silently dropped, preventing silent data loss during downstream outages. Adds inspection, single-entry redelivery, and removal endpoints under /deadletter, Prometheus DLQ metrics, and architecture/runbook documentation. Closes Utility-Protocol#124
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.
Summary
Implements Issue #124 — Dead Letter Queue for Failed Message Processing for the webhook delivery service.
Until now, a webhook that exhausted its retry budget (or was rejected by the SSRF shield) was silently dropped. That made a downstream receiver outage or a mis-configured endpoint look like silent data loss. This change routes permanently failed deliveries into a bounded dead letter queue so every message is preserved for inspection and operator-driven redelivery.
Changes
New:
webhook-delivery-service/src/deadLetterQueue.tsA bounded, in-memory DLQ keeping the failed payload, target URL, signing material (secret/private key), attempt history, failure reason, and last error for each dead letter.
reportDeadLetter(...): moves a permanently failed job into the DLQ.getDeadLetters() / getDeadLetter(id) / getDeadLetterCount(): inspection.popDeadLetter(id): atomic removal for redelivery.removeDeadLetter(id)/purgeDeadLetters(): discard operations.Delivery integration (
delivery.ts)reason: MAX_ATTEMPTS_EXHAUSTED.reason: SSRF_BLOCKED(no HTTP attempt is made).requeueDeadLetter(id): reconstructs a fresh delivery job from the stored entry (fresh retry budget) and re-enqueues it through the full signing + security + retry pipeline.HTTP API (
index.ts)GET /deadletter— list all dead letters (newest first) with count.GET /deadletter/:id— fetch a single dead letter.POST /deadletter/:id/requeue— push a dead letter back onto the active queue.DELETE /deadletter/:id— remove a single dead letter.DELETE /deadletter?confirm=true— purge the entire queue (explicit confirmation required)./health.Metrics (
metrics.ts)webhook_dead_letter_queue_size_currentwebhook_dead_letter_enqueued_total{reason}webhook_dead_letter_requeued_totalwebhook_dead_letter_discarded_totalTests (
deadLetterQueue.test.ts)13 new tests covering reporting, FIFO eviction, popping/redelivery, removal/purge, and full delivery integration (permanent failure → DLQ, SSRF → DLQ, requeue → successful redelivery, plus HTTP endpoint coverage). The new module is at 100% statement/branch coverage.
Docs
Updated
WEBHOOK_ARCHITECTURE.md(DLQ design section + new metrics) andWEBHOOK_RUNBOOK.md(DLQ inspection / redelivery / purge runbook).Verification
tsc --noEmitpasses.Closes #124