Context
motel emits CONSUMER for async children (pkg/synth/engine.go:449-455) but never emits PRODUCER, the fifth OTel span kind.
What the OTel spec says
Per the SpanKind spec and messaging semconv:
PRODUCER → the initiator of an asynchronous request (e.g. enqueuing a message); it typically ends before the corresponding CONSUMER span starts.
CONSUMER → the child of an asynchronous PRODUCER request (e.g. processing a dequeued message).
Today motel models only the consumer side of async work: an async: true call produces a CONSUMER child, but there is no explicit PRODUCER span representing the enqueue/publish operation. A realistic messaging trace usually has both: a PRODUCER span on the publishing service and a (often linked, separate-trace) CONSUMER span on the processing service.
Proposed work
- Allow an async send to be modelled with an explicit
PRODUCER span for the enqueue/publish step, distinct from the CONSUMER span that processes it
- Interplay with existing span-link support: producer and consumer commonly live in different traces joined by a span link (see
docs/examples/span-links.yaml) — make sure the two compose
- Decide how this is expressed in the DSL (e.g. a producer/consumer pairing on a messaging call) without breaking the current async/CONSUMER behaviour
- Tests asserting PRODUCER on the publish side and CONSUMER on the process side
Acceptance criteria
- Topology can produce explicit
PRODUCER spans for async producers
- Existing
CONSUMER behaviour preserved
- Producer/consumer pairing composes with span links
- Unit coverage + an example under
docs/examples/
References
Context
motel emits
CONSUMERfor async children (pkg/synth/engine.go:449-455) but never emitsPRODUCER, the fifth OTel span kind.What the OTel spec says
Per the SpanKind spec and messaging semconv:
PRODUCER→ the initiator of an asynchronous request (e.g. enqueuing a message); it typically ends before the correspondingCONSUMERspan starts.CONSUMER→ the child of an asynchronousPRODUCERrequest (e.g. processing a dequeued message).Today motel models only the consumer side of async work: an
async: truecall produces aCONSUMERchild, but there is no explicitPRODUCERspan representing the enqueue/publish operation. A realistic messaging trace usually has both: aPRODUCERspan on the publishing service and a (often linked, separate-trace)CONSUMERspan on the processing service.Proposed work
PRODUCERspan for the enqueue/publish step, distinct from theCONSUMERspan that processes itdocs/examples/span-links.yaml) — make sure the two composeAcceptance criteria
PRODUCERspans for async producersCONSUMERbehaviour preserveddocs/examples/References
pkg/synth/engine.go:449-455— kind selectiondocs/examples/span-links.yaml— existing producer/consumer linking example