Skip to content

First-class native DLQ → durable-storage recovery for all transports (generalize EnableDeadLetterQueueRecovery beyond RabbitMQ) #3103

Description

@jeremydmiller

Summary

Generalize native dead-letter-queue → durable-storage recovery beyond RabbitMQ, with consistent syntax, so Amazon SQS / Azure Service Bus (and other native-DLQ transports) can forward natively dead-lettered messages into the Wolverine durable message store.

Today

RabbitMQ has a first-class bridge: EnableDeadLetterQueueRecovery() registers DeadLetterQueueListener (a hosted service) that consumes the native DLQ, reconstructs the Envelope from x-death metadata, and calls IMessageInbox.MoveToDeadLetterStorageAsync(...) — so native dead letters land in wolverine_dead_letters and are queryable/replayable via IDeadLetters.

Amazon SQS and Azure Service Bus have no equivalent. Propagating their native DLQ messages into durable storage is a DIY pattern: a listener on the native DLQ + a handler that reconstructs the envelope and calls MoveToDeadLetterStorageAsync. Each transport's native dead-letter metadata differs (SQS attributes/redrive; ASB DeadLetterReason/DeadLetterErrorDescription on the $DeadLetterQueue sub-queue).

Ask

A first-class recovery feature for native-DLQ transports with similar syntax to RabbitMQ's EnableDeadLetterQueueRecovery() (on the SQS / ASB transport expressions) that consumes the native DLQ, reconstructs the Envelope from the transport's native dead-letter metadata, and persists via MoveToDeadLetterStorageAsync.

Why

Tools that manage the durable DLQ (e.g. CritterWatch) can only see/replay messages in the durable store — native-DLQ messages are invisible without this bridge. Today only RabbitMQ users get it out of the box. A consistent, built-in feature makes "make my native dead letters manageable" a one-call decision on every transport.

Pairs with

A queryable per-endpoint dead-letter-destination contract (filed separately) so monitors can detect un-bridged native DLQs and recommend enabling this.

Context: JasperFx/CritterWatch#351.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions