Envelope
Este conteúdo não está disponível em sua língua ainda.
Envelope<
T> =object
Defined in: src/internal/Mailbox.ts:6
Type Parameters
Section titled “Type Parameters”T = unknown
Properties
Section titled “Properties”context?
Section titled “context?”
readonlyoptionalcontext?:LogContextData
Defined in: src/internal/Mailbox.ts:15
Optional MDC snapshot captured at tell time. Propagated
through the actor’s onReceive so log lines emitted while
handling this message (and any tells issued from inside it)
carry the originating context. See LogContext.
enqueuedAtMs?
Section titled “enqueuedAtMs?”
readonlyoptionalenqueuedAtMs?:number
Defined in: src/internal/Mailbox.ts:43
Wall clock at first enqueue, stamped while the receiving actor has an
explain plan enabled or the system has metrics enabled — the two
consumers of it (ActorContext.enableExplainPlan and
actor_mailbox_wait_seconds). Absent otherwise, because a stamp is a
clock read on the framework’s hottest path and #411 removed exactly
these when nothing reads them.
A stashed message keeps its original stamp when replayed (prependUser
does not restamp), so the explain plan’s mailbox wait measures the whole
time from arrival to handling — stash residency included, which is what
a per-actor debugging view wants beside the stashed outcome that
explains it. The metric deliberately reads it differently; see
replayed.
Resolution is one millisecond (Date.now()), which is why the wait
histogram’s finest bucket is 1 ms rather than something sub-millisecond
that the clock could never distinguish.
message
Section titled “message”
readonlymessage:T
Defined in: src/internal/Mailbox.ts:7
replayed?
Section titled “replayed?”
readonlyoptionalreplayed?:boolean
Defined in: src/internal/Mailbox.ts:63
Set when this envelope re-entered the queue from the stash rather than arriving fresh, so enqueuedAtMs no longer marks the start of its current queue residency.
actor_mailbox_wait_seconds skips these. The aggregate has no labels
and no outcome column, so one actor stashing for thirty seconds while it
waits on a resource would land a thirty-second observation in the top
bucket and drown the queueing signal every other actor contributes —
where the explain plan shows the same message beside the stashed
entry that accounts for it. Stash residency is application semantics;
mailbox wait is meant to be backlog.
The other replay path, ActorCell.prependUserMessages, needs no marker:
it builds envelopes with no stamp at all, so it is already excluded.
Throttle re-parking is deliberately not marked — a throttled message
really is waiting in the queue for an actor that cannot keep up, which
is precisely what the metric is asking about.
sender
Section titled “sender”
readonlysender:ActorRef|null
Defined in: src/internal/Mailbox.ts:8
trace?
Section titled “trace?”
readonlyoptionaltrace?:SpanContext
Defined in: src/internal/Mailbox.ts:23
Optional active-span context captured at tell time. If the
tracing extension is enabled and the receiver also has it
enabled, the receiver’s actor.receive span links back to this
one as its parent — producing one coherent trace across actor
hops and cluster nodes. See Tracer.
undroppable?
Section titled “undroppable?”
readonlyoptionalundroppable?:boolean
Defined in: src/internal/Mailbox.ts:102
This envelope carries a lifecycle notification the framework generated and cannot send again, so no load-shedding policy may discard it (#729).
Two envelopes take it today, and the test for admitting a third is the property they share, not their subject: the framework built it, the framework sent it once, and nothing on the framework’s side still holds what it would take to send it again. Neither is application traffic, so neither is a message the caller who set the bound was choosing to lose.
The Terminated a death-watch delivers. The watch was installed through
context.watch, the framework promised to answer it, and the answer
happens once — there is no retry, no sender to back off, and the dying
cell has already cleared its watcher set by the time the queue decides.
A bounded mailbox that evicted it left the watcher believing a dead actor
was alive, with nothing but an actor_mailbox_dropped_total increment to
say so.
The websocket-accept a completed HTTP upgrade hands its hub (#717). The
wiring layer closed the only reference to a freshly-upgraded socket into
the per-connection actor’s factory and returned; there is no timer and no
second copy. A bounded hub that evicted it kept a socket nobody would
ever attach listeners to — buffering inbound frames with nothing to drain
them and holding its maxConnections slot — for the same one increment.
Set by ActorCell.postSignalEnvelope, which is the only door that
sets it, and read in three places: Mailbox.removeOldest and
Mailbox.removeNewest, so an eviction from either end steps over
it; BoundedMailbox.prependUser, so a bound that now applies to the
replay path admits it rather than shedding it (#772); and the cell’s
throttle gate, so onExcess: 'drop' does not silently consume it either.
It travels with the envelope rather than being remembered by the mailbox
because the envelope outlives any one queue position: it survives a
stash / unstashAll round trip and a prependUser replay, and both of
those hand it back to a bound that would otherwise get a second chance to
shed it.
