The native work item the ingress carries
Optional Readonlyattempt1-based delivery attempt. Present for 'queue' (from IJob.attempts)
and 'scheduler' (from ScheduledJob.attempts); ABSENT for
'messaging' and 'websocket'. Absent means "this ingress cannot tell
you" — never "first try": brokers redeliver and none tracks a delivery
count, so a fabricated 1 would lie on a fifth redelivery.
Optional ReadonlyconsumerIdentity of the CONSUMER this work item was dispatched to, so per-consumer state (an idempotency record) does not collide when one topic has several subscribers.
'messaging': the subscription's SubscribeOptions.queue when given,
otherwise subscription:<instance>:<n> — unique per subscription per
process. 'queue': the job name. ABSENT on 'scheduler' and
'websocket'.
A DISPATCH identity, not a capability and not a state bag — the envelope's
"no state, no services" rule stands (see the interface JSDoc).
Optional ReadonlyheadersTransport headers, populated on the 'messaging' arm from
MessageMetadata.headers and on the 'queue' arm from IJob.headers.
{} means the channel carried none; absent means there was no channel.
ABSENT on 'scheduler' deliberately, and that is a statement rather than
an omission: a tick has no upstream request, so there is no header to
carry and no trace to join. Adding the member "for symmetry" would erase
the distinction the three states exist for — an operator could no longer
tell "this work had no cause" from "the cause was lost".
ABSENT on 'websocket' for the different reason that a frame carries no
per-frame headers; the upgrade request's headers are the connection's.
ReadonlykindWhich ingress path produced this work item — the discriminator a behaviour branches on.
ReadonlynameThe route the work is addressed by: the queue job name, the scheduler job name, the broker topic, or the WebSocket route path.
ReadonlypayloadThe native work item: an IJob, a ScheduledJob, the message payload,
or the frame data.
Transport-neutral envelope for ONE unit of non-HTTP work.
Built per work item by the dispatch site (never reused across concurrent invocations) and handed to every behaviour in the chain. The wrapped handler keeps its NATIVE argument (
IJob,ScheduledJob,(message, metadata),(conn, data)); only the behaviour chain sees this envelope.There is deliberately no
stateslot and noservicesmember: the envelope is a per-item read-only value, and a behaviour needing a capability closes over it via itsRegistryFactoryarm instead. That closed-over capability is also how a TENANT concern is written: the tenant id is read frompayloadand scoped through the ctx-free members ofIMultiTenancyService(getRepositoryFor/prefixCacheKey) — itsIRequestContext-taking members are unreachable from an ingress path, which carries no request.The optional
consumermember added in M109a is a DISPATCH identity, not a capability and not a state bag: it names which subscriber a work item was dispatched to, so per-consumer state (an idempotency record) is keyed per subscriber rather than per topic. The "nostate, noservices" rule above stands unchanged — a behaviour still reaches a capability through itsRegistryFactoryarm, and a consumer value is read by the dispatch site, not resolved by the behaviour.Since
0.3.0