Skip to content

Commit c625b24

Browse files
committed
rearrange and enhancements
1 parent 0d5ab4a commit c625b24

3 files changed

Lines changed: 16 additions & 40 deletions

File tree

src/trace/context/extractors/durable-execution.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,12 @@ describe("DurableExecutionEventTraceExtractor", () => {
116116
CheckpointToken: "t-replay",
117117
InitialExecutionState: {
118118
Operations: [
119-
{
120-
Id: "op-1",
121-
Name: "_dd_trace_context_0",
122-
Status: "SUCCEEDED",
123-
StepDetails: {
124-
Result: JSON.stringify({
119+
{
120+
Id: "op-1",
121+
Name: "_datadog_0",
122+
Status: "SUCCEEDED",
123+
StepDetails: {
124+
Result: JSON.stringify({
125125
"x-datadog-trace-id": "149750110124521191",
126126
"x-datadog-parent-id": "538591322263933970",
127127
"x-datadog-sampling-priority": "1",

src/trace/context/extractors/durable-execution.ts

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,12 @@ export function getCheckpointToken(event: unknown): string | undefined {
110110
const TERMINAL_STATUSES = new Set(["SUCCEEDED", "FAILED", "CANCELLED", "STOPPED", "TIMED_OUT"]);
111111

112112
const TRACE_CHECKPOINT_NAME_PREFIX = "_datadog_";
113-
const LEGACY_TRACE_CHECKPOINT_NAME_PREFIX = "_dd_trace_context_";
114-
const TRACE_CHECKPOINT_NAME_PREFIXES = [
115-
TRACE_CHECKPOINT_NAME_PREFIX,
116-
LEGACY_TRACE_CHECKPOINT_NAME_PREFIX,
117-
];
118113

119114
function parseTraceCheckpointNumber(name: unknown): number | null {
120115
if (typeof name !== "string") return null;
121116

122-
const prefix = TRACE_CHECKPOINT_NAME_PREFIXES.find((candidate) => name.startsWith(candidate));
123-
if (!prefix) return null;
124-
125-
const suffix = name.slice(prefix.length);
117+
if (!name.startsWith(TRACE_CHECKPOINT_NAME_PREFIX)) return null;
118+
const suffix = name.slice(TRACE_CHECKPOINT_NAME_PREFIX.length);
126119
const n = Number.parseInt(suffix, 10);
127120
if (Number.isNaN(n) || String(n) !== suffix) return null;
128121
return n;
@@ -141,7 +134,6 @@ function isTraceCheckpointName(name: unknown): boolean {
141134
* dd-trace-js plugin via `tracer.inject(span, 'http_headers', headers)` so the
142135
* payload is a standard HTTP-style header dict.
143136
*
144-
* Also accepts legacy `_dd_trace_context_{N}` names for compatibility.
145137
*/
146138
function findLatestCheckpointHeaders(event: DurableExecutionEvent): Record<string, string> | null {
147139
const operations = event.InitialExecutionState?.Operations;
@@ -319,12 +311,14 @@ export function getCompletedOperationCount(event: unknown): number {
319311
* - no operation has terminal status
320312
* - operation count is <= 1
321313
*
314+
* The created span is parented to the current aws.lambda span context.
315+
*
322316
* Returns an object with { span, finish() } or null if not a durable execution.
323317
* Caller must call finish() when the invocation ends.
324318
*/
325319
export function createDurableExecutionRootSpan(
326320
event: unknown,
327-
extractedRootContext?: SpanContextWrapper | null,
321+
parentSpanContext?: unknown,
328322
): { span: any; finish: () => void } | null {
329323
if (!isDurableExecutionEvent(event)) {
330324
return null;
@@ -379,10 +373,9 @@ export function createDurableExecutionRootSpan(
379373
if (startTime !== undefined) {
380374
spanOptions.startTime = startTime;
381375
}
382-
if (extractedRootContext?.spanContext) {
383-
// Stay in the same trace as the upstream caller even when there is no
384-
// active scope yet. aws.lambda will be parented to this span downstream.
385-
spanOptions.childOf = extractedRootContext.spanContext;
376+
if (parentSpanContext) {
377+
// Root span is modeled as a child of aws.lambda.
378+
spanOptions.childOf = parentSpanContext;
386379
}
387380

388381
const span = tracer.startSpan("aws.durable-execution", spanOptions);

src/trace/listener.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
} from "./durable-function-context";
2828
import { XrayService } from "./xray-service";
2929
import { AUTHORIZING_REQUEST_ID_HEADER } from "./context/extractors/http";
30-
import { createDurableExecutionRootSpan } from "./context/extractors/durable-execution";
3130
import { getSpanPointerAttributes, SpanPointerAttributes } from "../utils/span-pointers";
3231
export type TraceExtractor = (event: any, context: Context) => Promise<TraceContext> | TraceContext;
3332

@@ -103,7 +102,6 @@ export class TraceListener {
103102
private wrappedCurrentSpan?: SpanWrapper;
104103
private triggerTags?: { [key: string]: string };
105104
private lambdaSpanParentContext?: SpanContext;
106-
private durableRootSpan?: { span: any; finish: () => void };
107105
private spanPointerAttributesList: SpanPointerAttributes[] | undefined;
108106

109107
public get currentTraceHeaders() {
@@ -145,25 +143,16 @@ export class TraceListener {
145143
traceSource: this.contextService.traceSource,
146144
});
147145
}
148-
// Create the durable execution root span before everything else so later
149-
// spans can parent correctly. Root creation is gated in
150-
// createDurableExecutionRootSpan() and only happens for likely first
151-
// invocations; replay invocations return null. The root span inherits
152-
// trace_id and sampling from spanContextWrapper, so anything parented to
153-
// it (aws.lambda below) joins the same trace automatically.
154-
this.durableRootSpan = createDurableExecutionRootSpan(event, spanContextWrapper) ?? undefined;
155-
const durableRootSpanContext = this.durableRootSpan?.span?.context();
156-
157146
if (this.config.createInferredSpan) {
158147
this.inferredSpan = this.inferrer.createInferredSpan(
159148
event,
160149
context,
161-
durableRootSpanContext || parentSpanContext,
150+
parentSpanContext,
162151
this.config.encodeAuthorizerContext,
163152
);
164153
}
165154

166-
this.lambdaSpanParentContext = this.inferredSpan?.span || durableRootSpanContext || parentSpanContext;
155+
this.lambdaSpanParentContext = this.inferredSpan?.span || parentSpanContext;
167156
this.context = context;
168157
const eventSource = parseEventSource(event);
169158
this.triggerTags = extractTriggerTags(event, context, eventSource);
@@ -320,12 +309,6 @@ export class TraceListener {
320309
this.injectAuthorizerSpan(result, event?.requestContext?.requestId, finishTime || Date.now());
321310
}
322311

323-
// Finish the durable execution root span after all other spans.
324-
if (this.durableRootSpan) {
325-
this.durableRootSpan.finish();
326-
this.durableRootSpan = undefined;
327-
}
328-
329312
// Reset singletons and trace context
330313
this.stepFunctionContext = undefined;
331314
this.durableFunctionContext = undefined;

0 commit comments

Comments
 (0)