Skip to content

Commit 14cb421

Browse files
committed
Make segment-span deferral enable-only
1 parent 487a7e4 commit 14cb421

2 files changed

Lines changed: 20 additions & 12 deletions

File tree

packages/core/src/tracing/sentrySpan.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,18 @@ const DEFERRED_SEGMENT_SPAN_CAPTURES = new WeakMap<Client, (capture: () => void)
6868
const CAPTURED_SPANS = new WeakSet<Span>();
6969

7070
/**
71-
* Opt a client into (or out of) deferring its segment-span transaction capture.
72-
* Set by the SDK client during setup (e.g. the Node SDK); see {@link DEFERRED_SEGMENT_SPAN_CAPTURES}.
71+
* Defer a client's segment-span transaction capture. Set once by the SDK during setup (e.g. the Node
72+
* SDK); see {@link DEFERRED_SEGMENT_SPAN_CAPTURES}. Idempotent, and deferral stays on for the client's
73+
* lifetime (there is no opt-out: deferral is a set-once-at-setup property, never toggled mid-session).
7374
*
7475
* The transaction is otherwise assembled from the live span tree the instant a root span ends, which
7576
* drops children whose async instrumentation closes them later (a diagnostics-channel `asyncEnd`
76-
* callback in the same tick, or engine spans replayed on a later tick). A debounced timer the same
77-
* one the OpenTelemetry span exporter usesdelays the snapshot just enough for those later span ends
78-
* to land first. Pending captures are drained synchronously on the client's `flush` hook so
77+
* callback in the same tick, or engine spans replayed on a later tick). A debounced timer (the same one
78+
* the OpenTelemetry span exporter uses) delays the snapshot just enough for those later span ends to
79+
* land first. Pending captures are drained synchronously on the client's `flush` hook so
7980
* `Sentry.flush()` / `client.close()` cannot resolve before they run.
8081
*/
81-
export function _INTERNAL_setDeferSegmentSpanCapture(client: Client, defer: boolean): void {
82-
if (!defer) {
83-
DEFERRED_SEGMENT_SPAN_CAPTURES.delete(client);
84-
return;
85-
}
86-
82+
export function _INTERNAL_setDeferSegmentSpanCapture(client: Client): void {
8783
if (DEFERRED_SEGMENT_SPAN_CAPTURES.has(client)) {
8884
return;
8985
}

packages/core/test/lib/tracing/sentrySpan.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { describe, expect, it, test, vi } from 'vitest';
22
import { getCurrentScope } from '../../../src/currentScopes';
33
import { setCurrentClient } from '../../../src/sdk';
44
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../../../src/semanticAttributes';
5-
import { SentrySpan } from '../../../src/tracing/sentrySpan';
5+
import { _INTERNAL_setDeferSegmentSpanCapture, SentrySpan } from '../../../src/tracing/sentrySpan';
66
import { SPAN_STATUS_ERROR } from '../../../src/tracing/spanstatus';
77
import { markSpanForOtelSourceInference, spanSourceWasExplicitlySet } from '../../../src/tracing/utils';
88
import type { SpanJSON } from '../../../src/types/span';
@@ -132,6 +132,18 @@ describe('SentrySpan', () => {
132132
});
133133
});
134134

135+
describe('_INTERNAL_setDeferSegmentSpanCapture', () => {
136+
it('registers the flush listener once and is idempotent on repeated enable', () => {
137+
const client = new TestClient(getDefaultTestClientOptions());
138+
const onSpy = vi.spyOn(client, 'on');
139+
140+
_INTERNAL_setDeferSegmentSpanCapture(client);
141+
_INTERNAL_setDeferSegmentSpanCapture(client);
142+
143+
expect(onSpy.mock.calls.filter(([hook]) => hook === 'flush')).toHaveLength(1);
144+
});
145+
});
146+
135147
describe('end', () => {
136148
test('simple', () => {
137149
const span = new SentrySpan({});

0 commit comments

Comments
 (0)