Skip to content

Sticky wire-exchange trace id derived from message content - #771

Merged
ar merged 1 commit into
mainfrom
feature/sticky-trace-id
Sep 4, 2026
Merged

ar merged 1 commit into
mainfrom
feature/sticky-trace-id

Conversation

@ar

@ar ar commented Sep 4, 2026

Copy link
Copy Markdown
Member

Implements #769.

What

One trace id per wire exchange, derived from message content so request and response share it with no carrier on the wire and regardless of protocol version.

ISOMsg

  • naturalTraceId(): first two MTI digits plus the trace-id fields present (default 3, 7, 11, 12, 41, 42, trimmed; 37 and 32 are excluded because a server often mints them, 7 and 12 keep a wrapped STAN from linking to old exchanges), hashed to a 32-hex UUID. null when none of the key fields is present. setTraceIdFields(int...) tunes the field list system-wide.
  • setTraceId(String) / getClaimedTraceId(): an explicitly asserted id. Transient, copied by clone, never packed.
  • getTraceId(): the effective id. Natural when computable, else the claim, else a random id minted once and kept as the claim.

BaseChannel send and receive events: trace-id = the message's effective id; new session tag = socket UUID (which used to be the trace id); trace-claimed = the claimed id, only when it differs from the effective one.

IncomingListener puts ContextConstants.TRACE_ID (new) into the Context.

TransactionManager uses the Context trace id for the transaction event, falling back to the per-transaction id when absent.

SendResponse claims the Context trace id on the response when it has no claim of its own, so a response whose key fields changed still links back through trace-claimed.

Not changed

No wire field. No thread-locals. LogEvent trace-id format stays 32 hex. Session events in ISOServer are unchanged.

Behaviour notes

  • A retransmission (0201) shares the original's id: the MTI class and key fields are the same. That is the same wire exchange for correlation purposes.
  • A MUX-originated request from a participant gets its own natural id; linking it to the inbound transaction's id is a follow-up (claim from the Context in QueryHost).
  • CMF DE-113.22 adopt/echo is a follow-up once a DE-113 subfield packager exists.

Tests

  • ISOMsgTest: request/response share the natural id, a different STAN differs, claim copied by clone and never overrides the natural id, a message without key fields gets a stable minted id.
  • IncomingListenerTest (new): the queued Context carries the message's id.
  • ISOServerTest.testChannelEventsCarryTheExchangeTraceIdAndSessionTag (new): a real client-to-server exchange; the client's send event and the server's receive event carry the same trace-id, both carry session, neither carries trace-claimed.
  • Full :jpos:test and :jpos:javadoc pass.

Release note

Channel send / receive events: trace-id now identifies the wire exchange rather than the connection; the connection id moved to the session tag. Consumers that joined channel events on trace-id per connection should use session.

ISOMsg.getTraceId() returns an id derived from the MTI class and fields
3, 7, 11, 12, 41 and 42 (configurable system-wide), so a request and its
response share one id with no wire carrier and regardless of protocol
version. An explicitly asserted id (setTraceId) is kept as a transient
claim, copied by clone and never packed; a message without key fields
gets a random id minted once.

Channel send and receive events carry the message's id as trace-id, the
socket UUID moves to a session tag, and trace-claimed records a claim
that differs from the effective id. IncomingListener puts the id in the
Context under ContextConstants.TRACE_ID, the TransactionManager uses it
for the transaction event, and SendResponse claims it on the response.

Closes #769
@ar
ar merged commit 7276724 into main Sep 4, 2026
1 check passed
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.

1 participant