Skip to content

Add PropagatingInMemory testkit backend#1335

Draft
kubukoz wants to merge 3 commits into
typelevel:mainfrom
kubukoz:propagating-test-backend
Draft

Add PropagatingInMemory testkit backend#1335
kubukoz wants to merge 3 commits into
typelevel:mainfrom
kubukoz:propagating-test-backend

Conversation

@kubukoz

@kubukoz kubukoz commented Jul 3, 2026

Copy link
Copy Markdown
Member

What

Adds PropagatingInMemory, a testkit EntryPoint/Span implementation that models trace context propagation, complementing the existing InMemory.

InMemory records a command log but gives every span an empty/inherited kernel and a None spanId, so it can't express parentage — you can't assert that a continued span is really a child of the span whose kernel was propagated to it. PropagatingInMemory:

  • assigns each span a distinct id (via a Concurrent counter), exposed idiomatically through spanId and its kernel (under the X-Natchez-Span-Id header);
  • resolves an explicit parentKernel (from Span.Options.parentKernel) over the enclosing span when creating a child — the semantic real backends implement;
  • exposes the resolved parent as Span.parentId, and records each created span (Recorded(name, id, parentId)) queryable via EntryPoint#spans.

Why

Testing that instrumentation propagates trace context across boundaries (e.g. a cache loader that continues a span from a kernel handed to it) currently isn't possible with the shipped testkit — every InMemory span hands out the same kernel and no id. This backend makes those assertions straightforward while leaving InMemory completely untouched.

Notes / open questions

  • New file, no changes to InMemory — all existing core-tests fixtures pass unchanged.
  • PropagatingInMemorySuite demonstrates: distinct ids surfaced via spanId/kernel, child parented to enclosing span, explicit parentKernel winning over the enclosing span, and concurrent children each keeping their own parent with no id collision.
  • Draft: only Scala 2.13/JVM was compiled locally; the source is written cross-friendly but JS/Native/2.12 are unverified. Naming (PropagatingInMemory, Recorded, spans) and whether this belongs as a sibling vs. an extension of InMemory are open to feedback.

🤖 Generated with Claude Code

InMemory records a command log but gives every span an empty/inherited
kernel and a None spanId, so it cannot model trace context propagation.
PropagatingInMemory assigns each span a distinct id, exposes it via spanId
and kernel, and resolves an explicit parentKernel over the enclosing span
when creating children (exposing the resolved parent as Span.parentId).
This makes it possible to assert that a continued span is really a child
of the span whose kernel was propagated to it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kubukoz kubukoz force-pushed the propagating-test-backend branch from a196862 to 5da13ce Compare July 3, 2026 22:20
kubukoz and others added 2 commits July 4, 2026 00:36
groupMapReduce is 2.13+. Replaced with groupBy(_.name).map(k -> v.head),
which keeps the first Recorded per name identically and compiles on 2.12.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scaladoc rejects a /** */ comment on a constructor parameter (val parentId)
as an "unmoored doc comment", failing doc generation under fatal warnings.
Made it a regular // comment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant