feat(otel): add useLinksInsteadOfParent option to HatchetInstrumentor#3804
feat(otel): add useLinksInsteadOfParent option to HatchetInstrumentor#3804purva-8 wants to merge 3 commits intohatchet-dev:mainfrom
Conversation
Fire-and-forget child runs (runNoWait fan-outs) should not extend their parent trace's duration until the slowest child finishes. OTel span links are the correct primitive: the child starts a new root trace with a navigable link back to the spawning span. Add a useLinksInsteadOfParent predicate to HatchetInstrumentationConfig. When it returns true for a given actionId, handleStartStepRun starts the step span without a parent context and instead attaches the extracted SpanContext as a link. Default is undefined, preserving all existing parent-child behaviour exactly. Closes hatchet-dev#3641 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@purva-8 is attempting to deploy a commit to the Hatchet Team on Vercel. A member of the Team first needs to authorize it. |
|
Promptless prepared a documentation update related to this change. Added the new |
There was a problem hiding this comment.
Pull request overview
Adds a new OpenTelemetry configuration option to control whether hatchet.start_step_run spans should be parented to the spawning span (current behavior) or started as a new root trace with a span link back (for fire-and-forget fan-out patterns), addressing #3641.
Changes:
- Introduces
useLinksInsteadOfParent(actionId) => booleanonHatchetInstrumentorconfig. - Updates
handleStartStepRuninstrumentation to create span links (instead of a parent context) when the predicate returnstrue. - Adds Jest unit tests covering default behavior, predicate true/false, actionId forwarding, and invalid context fallback.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
sdks/typescript/src/opentelemetry/instrumentor.ts |
Adds config predicate and switches start_step_run to link-based trace semantics when enabled. |
sdks/typescript/src/opentelemetry/instrumentor.test.ts |
New unit tests validating link vs parent-child behavior for start_step_run. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Closes #3641
Problem
HatchetInstrumentorcurrently forces every spawned run into a parent→child OTel relationship. For fire-and-forget patterns (runNoWaitfan-outs, long-running children, rate-limited queues) this is wrong: the parent trace stays open until the slowest child finishes, which inflates p50/p95 metrics and pollutes the waterfall view.OTel's span links are the right primitive here — the child starts a new root trace with a navigable link back to the spawning span, so the parent trace closes as soon as the spawn loop returns.
Solution
Add a
useLinksInsteadOfParentpredicate toHatchetInstrumentationConfig:When the predicate returns
truefor a givenactionId:handleStartStepRunextracts theSpanContextfrom the incomingadditionalMetadata(same as before)startActiveSpan(name, { kind, attributes, links: [{ context: parentSpanCtx }] }, fn)— no parent context argument, so the child span becomes a root in a new trace with a link pointing back to the spawning spantraceparentin metadata), the links array is empty and the span still starts cleanly as a rootWhen the predicate returns
false(or is not provided):startActiveSpan(name, opts, parentContext, fn)path is used - zero behaviour changeDefault:
undefined→ all spans use parent-child semantics, fully backwards compatible.Changes
sdks/typescript/src/opentelemetry/instrumentor.ts- new config option + updated_patchHandleStartStepRunsdks/typescript/src/opentelemetry/instrumentor.test.ts- 5 unit tests (default, predicate=false, predicate=true, actionId forwarding, invalid-context fallback)Test plan
pnpm test:unit- all 195 tests pass (2 pre-existing skips)tsc --noEmit- no type errors