Skip to content

Expose per-endpoint dead-letter destination as a queryable contract (#3104)#3107

Merged
jeremydmiller merged 1 commit into
mainfrom
feature-3104-dlq-destination-contract
Jun 15, 2026
Merged

Expose per-endpoint dead-letter destination as a queryable contract (#3104)#3107
jeremydmiller merged 1 commit into
mainfrom
feature-3104-dlq-destination-contract

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Closes #3104.

Summary

There was no transport-agnostic way to ask "where do this endpoint's dead letters go?" — it was encoded in per-transport config (DeadLetterQueueName, DeadLetterQueueMode, the ASB $DeadLetterQueue sub-queue, …). This adds a uniform, queryable contract so a monitor like CritterWatch can detect endpoints that dead-letter natively without recovery to durable storage and recommend the fix — without leaking transport-specific knowledge.

The contract

A transport-agnostic enum:

public enum DeadLetterStorageMode { Durable, Native, NativeWithRecovery }

exposed two ways:

Per-transport reporting

Transport Reports
RabbitMQ Native (DLX) · NativeWithRecovery when EnableDeadLetterQueueRecovery() is set · Durable for WolverineStorage mode
Amazon SQS Native when a DLQ is configured · Durable when disabled
Azure Service Bus Native (managed DLQ queue / native sub-queue) · Durable when disabled
Redis / Kafka / GCP Pub/Sub Native when a native DLQ is configured · Durable otherwise
Local / others Durable

Only RabbitMQ can report NativeWithRecovery today, since it's the only transport with native→durable recovery on main. Once #3103 (recovery for SQS/Azure Service Bus) merges, a tiny follow-up can promote those transports to NativeWithRecovery when recovery is enabled. The enum value is in place for it.

Documentation

New "Introspecting an Endpoint's Dead Letter Destination" section on the Dead Letter Storage page, with the enum semantics table and how to read the contract.

Tests

  • Core: descriptor defaults to Durable and doesn't duplicate the value in Properties.
  • Per-transport contract tests for SQS, Azure Service Bus, and RabbitMQ (infrastructure-free — direct endpoint construction).

Verification

  • Full wolverine.slnx Release build clean (0 warnings / 0 errors).
  • All new tests green (3 core + 3 SQS + 3 ASB + 3 RabbitMQ).

Pairs with

#3103 — together a monitor can (a) detect un-bridged native DLQs via this contract and (b) point users at the one-call EnableDeadLetterQueueRecovery() fix.

🤖 Generated with Claude Code

…3104)

Adds a transport-agnostic DeadLetterStorageMode enum { Durable, Native,
NativeWithRecovery } and a virtual Endpoint.DeadLetterStorage (default
Durable), surfaced as a first-class typed field on EndpointDescriptor (the
GH-3009 pattern CritterWatch reads). Monitoring tools can now introspect
where each endpoint's dead letters go — durable store vs native broker DLQ,
and whether native->durable recovery is enabled — without transport-specific
knowledge, to detect un-bridged native DLQs and recommend recovery.

Per-transport reporting:
- RabbitMQ: Native (DLX) / NativeWithRecovery when EnableDeadLetterQueueRecovery
  is set / Durable for WolverineStorage mode.
- SQS, Azure Service Bus, Redis, Kafka, GCP Pub/Sub: Native when a native DLQ
  is configured, Durable when disabled.
- Everything else (local, etc.): Durable.

The DeadLetterStorage row is dropped from the reflected Properties to avoid
double-shipping alongside the typed field (matching Mode/IsListener).

Docs: new "Introspecting an Endpoint's Dead Letter Destination" section on
the dead-letter-storage page.

Tests: core descriptor tests (default Durable + no Properties duplication)
and per-transport contract tests for SQS, Azure Service Bus, and RabbitMQ.

Closes #3104.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller merged commit e4b51bb into main Jun 15, 2026
24 checks passed
This was referenced Jun 15, 2026
This was referenced Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose per-endpoint dead-letter destination (native vs durable) as a queryable contract

1 participant