Skip to content

otel-thread-ctx: add ThreadContext.invalidate() to flip valid byte - #383

Merged
szegedi merged 1 commit into
mainfrom
szegedi/otel-thread-ctx-invalidate
Aug 7, 2026
Merged

otel-thread-ctx: add ThreadContext.invalidate() to flip valid byte#383
szegedi merged 1 commit into
mainfrom
szegedi/otel-thread-ctx-invalidate

Conversation

@szegedi

@szegedi szegedi commented Aug 6, 2026

Copy link
Copy Markdown

Summary

Adds ThreadContext.invalidate() to the OTEP-4947 writer's addon-exposed API. Writes 0 into the record's valid header byte in place, using the same volatile + atomic_signal_fence protocol the constructor and Append() already use for header bytes an out-of-process reader can race with.

Why

When an SDK finishes a span, clearContext() on the current async-context frame detaches the ThreadContext only from that frame. Sibling and detached-continuation frames that already inherited the reference keep holding the same JS object — and with it the same underlying native record — so an eBPF reader sampling those contexts still sees the finished span's trace / span IDs as active. This is admittedly rare, but a corner case worth addressing.

Every async-context frame holding the same ThreadContext reference observes the same shared record buffer, so a single invalidate() drops the record out of scope for every such frame at once. Readers see valid=0 and MUST ignore the record per OTEP-4947.

Addresses Codex review point #2 on DataDog/dd-trace-js#9210 ("Clear inherited contexts after finish"). The dd-trace-js follow-up wiring onSpanFinishedcached.context.invalidate() will land in a separate PR after this addon change ships.

Same change ported to upstream at polarsignals/custom-labels (branch `otel-thread-ctx-invalidate`).

Test plan

  • Local `npm run compile` + `npm run rebuild` clean.
  • 3 new mocha cases: valid byte flips in place, idempotent, appendAttributes after invalidate mutates attrs_data but keeps valid=0.
  • Docker test suite currently fails on `origin/main` too (`Cannot find module './heap-profiler-bindings'`) — unrelated to this change; will unblock via a separate fix.

Jira: PROF-15665

When an SDK finishes a span, calling clearContext() on the current
async-context frame detaches the ThreadContext only from that frame.
Sibling and detached-continuation frames that already inherited the
reference keep holding the same JS object — and with it the same
underlying native record — so an out-of-process reader sampling those
threads still sees the finished span's trace / span IDs as active.

invalidate() writes 0 to the record's `valid` header byte in place,
using the same volatile+atomic_signal_fence protocol the constructor
and Append() use for header bytes readers may race with. Because
every async-context frame holding this ThreadContext reference
observes the same shared record buffer, a single invalidate() drops
the record out of scope for every such frame at once — readers see
valid=0 and MUST ignore the record per OTEP-4947.

The method is idempotent, safe under repeated calls, and orthogonal
to attrs_data mutation: appendAttributes after invalidate is still
observable in the record bytes, but readers honor the valid=0 flag
regardless.
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Overall package size

Self size: 2.46 MB
Deduped: 3.16 MB
No deduping: 3.16 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------| | pprof-format | 2.3.0 | 503.97 kB | 503.97 kB | | source-map | 0.8.0 | 185.66 kB | 185.66 kB | | node-gyp-build | 4.8.4 | 13.86 kB | 13.86 kB |

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@datadog-prod-us1-6

This comment has been minimized.

@szegedi szegedi added the semver-minor Usually minor non-breaking improvements label Aug 6, 2026
@szegedi
szegedi marked this pull request as ready for review August 6, 2026 14:31
@szegedi
szegedi merged commit cbcfa11 into main Aug 7, 2026
70 of 71 checks passed
@szegedi
szegedi deleted the szegedi/otel-thread-ctx-invalidate branch August 7, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver-minor Usually minor non-breaking improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants