Add PropagatingInMemory testkit backend - #1335
Conversation
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>
a196862 to
5da13ce
Compare
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>
|
This looks pretty useful! I was about to start working on something similar (I stumbled across a bug in some application code and wanted to use the lineages
IMO this would be more useful as an extension or update to I suppose the downside is that existing tests with lineages might be broken? I wonder who's using that to test |
There was a problem hiding this comment.
I noticed there are no tests that use continue or continueOrElseRoot. It'd probably be a good idea to test propagation via those paths too.
| kernel: Kernel, | ||
| options: natchez.Span.Options | ||
| ): Resource[F, Span[F]] = | ||
| Resource.eval(newSpan(name, kernel.toHeaders.get(SpanIdHeader), log, nextId, options)) |
There was a problem hiding this comment.
There's a comment on EntryPoint#continue that says "If the required headers are not present in kernel an exception will be raised in F." I wonder if SpanIdHeader is not present in kernel, this should raise instead of silently falling back to effectively a new root span?
What
Adds
PropagatingInMemory, a testkitEntryPoint/Spanimplementation that models trace context propagation, complementing the existingInMemory.InMemoryrecords a command log but gives every span an empty/inheritedkerneland aNonespanId, 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:Concurrentcounter), exposed idiomatically throughspanIdand itskernel(under theX-Natchez-Span-Idheader);parentKernel(fromSpan.Options.parentKernel) over the enclosing span when creating a child — the semantic real backends implement;Span.parentId, and records each created span (Recorded(name, id, parentId)) queryable viaEntryPoint#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
InMemoryspan hands out the same kernel and no id. This backend makes those assertions straightforward while leavingInMemorycompletely untouched.Notes / open questions
InMemory— all existingcore-testsfixtures pass unchanged.PropagatingInMemorySuitedemonstrates: distinct ids surfaced viaspanId/kernel, child parented to enclosing span, explicitparentKernelwinning over the enclosing span, and concurrent children each keeping their own parent with no id collision.PropagatingInMemory,Recorded,spans) and whether this belongs as a sibling vs. an extension ofInMemoryare open to feedback.🤖 Generated with Claude Code