Перейти к содержимому
Русский

DeadLetterQueue

Это содержимое пока не доступно на вашем языке.

Defined in: src/deadletters/DeadLetterQueue.ts:99

Bounded, optionally durable record of the messages this system could not deliver (#433).

Before this existed, DeadLetterRef published each letter on the event stream and returned. With no subscriber — the default — the letter was simply gone, which made “what did we drop during that incident?” a question the framework could not answer after the fact. The queue is the subscriber that is always there: it captures at the single choke point every dead letter already passes through, so nothing has to be routed to it and no emitter has to know it exists.

Capture sits upstream of publication and of any future suppression. A rate limiter or sampler over the dead-letter stream is a reasonable thing to want (#1179), but one that dropped letters before this sink would quietly turn a durable record into a lossy sample while every document still called it complete. DeadLetterRef therefore calls the sink first and publishes second.

What it sees only when asked. A message discarded by a bounded or priority mailbox reaches the queue when — and only when — that mailbox was built with deadLetterDrops: true (#773). The seam now carries the envelope rather than only a reason, so DroppingMailbox has something to hand over; what stays opt-in is the routing, because a drop happens on the sender’s stack and turning each one into a capture plus a publish undoes the bound it went through. Left off, an overflow shows up in actor_mailbox_dropped_total and nowhere here — which is a choice the actor’s author made, not a gap in the record.

Not every store retains a letter. Under metrics the counter is the only record: list stays empty and replay answers unknown-entry for every id, which is honest rather than degraded — nothing was kept, so there is nothing to hand back.

Persistence is resolved lazily, through a dynamic import, so that a consumer importing Actor does not pull a journal — and its codec, and its plugin registry — into their bundle for a feature they left off.

new DeadLetterQueue(system, options?): DeadLetterQueue

Defined in: src/deadletters/DeadLetterQueue.ts:133

ActorSystem

DeadLetterQueueOptions = {}

DeadLetterQueue

get capacity(): number

Defined in: src/deadletters/DeadLetterQueue.ts:158

How many letters the ring holds before it drops its oldest.

Exposed for the DevTools panel (#553), which reports how full the queue is: a count alone cannot say whether 200 letters is a quiet system or one that has already begun losing them.

number


get store(): DeadLetterStore

Defined in: src/deadletters/DeadLetterQueue.ts:149

Where this queue keeps what it captures.

DeadLetterStore

clear(): Promise<void>

Defined in: src/deadletters/DeadLetterQueue.ts:262

Forget everything held. The durable log is compacted to match.

Promise<void>


flush(): Promise<void>

Defined in: src/deadletters/DeadLetterQueue.ts:280

Settle the durable writes issued so far.

Registered as a CoordinatedShutdown task in before-actor-system-terminate and awaited again once the actor tree is down. Both are needed and neither is redundant: the phase catches the letters a running system produced, and the second catches the ones the teardown itself produces — a stashed message, a mailbox drained past its cell — which are emitted after every phase has run and are, for a shutting-down system, most of them.

Promise<void>


get(id): Promise<DeadLetterEntry | undefined>

Defined in: src/deadletters/DeadLetterQueue.ts:186

One entry by id, or undefined if it has been replayed or aged out.

string

Promise<DeadLetterEntry | undefined>


list(filter?): Promise<readonly DeadLetterEntry[]>

Defined in: src/deadletters/DeadLetterQueue.ts:172

Captured letters, newest first, narrowed by filter.

Newest first because the question that brings someone here is almost always “what just broke”, and a queue at its cap would otherwise open on the oldest thing it still happens to hold.

Asynchronous even though the letters are held in memory: a persistent queue has a previous run’s log to read back first, and a synchronous reader would have answered “nothing” for however long that took — exactly at the moment after a restart when the answer matters most.

DeadLetterFilter = {}

Promise<readonly DeadLetterEntry[]>


replay(id, alternateRecipientPath?): Promise<DeadLetterReplayResult>

Defined in: src/deadletters/DeadLetterQueue.ts:225

Hand a captured letter back — to the actor it was addressed to, or to alternateRecipientPath instead.

Removes the entry before redelivering, and remembers the message so that a second failure comes back as the same entry with a higher replayCount rather than as a fresh one. Without that bookkeeping an operator retrying a poison message would add an entry per attempt while each attempt still looked like a first — the queue growing on exactly the letters it should be refusing. Past maxReplays the letter is quarantined and this refuses to send it.

The alternate replaces the destination and nothing else. The sender is still the recorded one, so the recipient’s sender answers the actor that originally sent the message and a reply goes where a reply always would. The recorded path is not resolved at all when an alternate is given: redirecting is most useful precisely when the original address is gone for good — a renamed actor, a shard that moved, a typo in a spawn — and requiring the dead address to still exist would refuse exactly those cases.

An alternate does not reset maxReplays. The cap bounds how many times this letter is redelivered, not how many times one recipient is asked, so a quarantined letter stays refused however it is addressed. Letting a different path grant a fresh budget would hand the unbounded retry loop back to any operator willing to alternate between two paths — which is the loop the cap exists to close.

If the letter dead-letters again at the alternate it returns as the same entry, now recording the alternate as its recipientPath: that is where the message actually failed this time, and it is what the next person reading the queue needs to see.

string

string

Promise<DeadLetterReplayResult>