Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c15f360

Browse files
authoredMar 27, 2020
Do not export empty span lists (open-telemetry#896)
* chore: remove in-memory polling timer
1 parent 6afa63c commit c15f360

File tree

2 files changed

+52
-18
lines changed

2 files changed

+52
-18
lines changed
 

‎packages/opentelemetry-tracing/src/export/BatchSpanProcessor.ts

+21-18
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ const DEFAULT_BUFFER_TIMEOUT_MS = 20_000;
3131
export class BatchSpanProcessor implements SpanProcessor {
3232
private readonly _bufferSize: number;
3333
private readonly _bufferTimeout: number;
34+
3435
private _finishedSpans: ReadableSpan[] = [];
35-
private _lastSpanFlush = Date.now();
36-
private _timer: NodeJS.Timeout;
36+
private _timer: NodeJS.Timeout | undefined;
3737
private _isShutdown = false;
3838

3939
constructor(private readonly _exporter: SpanExporter, config?: BufferConfig) {
@@ -43,13 +43,6 @@ export class BatchSpanProcessor implements SpanProcessor {
4343
config && typeof config.bufferTimeout === 'number'
4444
? config.bufferTimeout
4545
: DEFAULT_BUFFER_TIMEOUT_MS;
46-
47-
this._timer = setInterval(() => {
48-
if (this._shouldFlush()) {
49-
this._flush();
50-
}
51-
}, this._bufferTimeout);
52-
unrefTimer(this._timer);
5346
}
5447

5548
forceFlush(): void {
@@ -73,7 +66,6 @@ export class BatchSpanProcessor implements SpanProcessor {
7366
if (this._isShutdown) {
7467
return;
7568
}
76-
clearInterval(this._timer);
7769
this.forceFlush();
7870
this._isShutdown = true;
7971
this._exporter.shutdown();
@@ -82,22 +74,33 @@ export class BatchSpanProcessor implements SpanProcessor {
8274
/** Add a span in the buffer. */
8375
private _addToBuffer(span: ReadableSpan) {
8476
this._finishedSpans.push(span);
77+
this._maybeStartTimer();
8578
if (this._finishedSpans.length > this._bufferSize) {
8679
this._flush();
8780
}
8881
}
8982

90-
private _shouldFlush(): boolean {
91-
return (
92-
this._finishedSpans.length >= 0 &&
93-
Date.now() - this._lastSpanFlush >= this._bufferTimeout
94-
);
95-
}
96-
9783
/** Send the span data list to exporter */
9884
private _flush() {
85+
this._clearTimer();
86+
if (this._finishedSpans.length === 0) return;
9987
this._exporter.export(this._finishedSpans, () => {});
10088
this._finishedSpans = [];
101-
this._lastSpanFlush = Date.now();
89+
}
90+
91+
private _maybeStartTimer() {
92+
if (this._timer !== undefined) return;
93+
94+
this._timer = setTimeout(() => {
95+
this._flush();
96+
}, this._bufferTimeout);
97+
unrefTimer(this._timer);
98+
}
99+
100+
private _clearTimer() {
101+
if (this._timer !== undefined) {
102+
clearTimeout(this._timer);
103+
this._timer = undefined;
104+
}
102105
}
103106
}

‎packages/opentelemetry-tracing/test/export/BatchSpanProcessor.test.ts

+31
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ describe('BatchSpanProcessor', () => {
4545
});
4646
afterEach(() => {
4747
exporter.reset();
48+
sinon.restore();
4849
});
4950

5051
describe('constructor', () => {
@@ -142,5 +143,35 @@ describe('BatchSpanProcessor', () => {
142143
processor.forceFlush();
143144
assert.strictEqual(exporter.getFinishedSpans().length, 5);
144145
});
146+
147+
it('should not export empty span lists', done => {
148+
const spy = sinon.spy(exporter, 'export');
149+
const clock = sinon.useFakeTimers();
150+
151+
const tracer = new BasicTracerProvider({
152+
sampler: ALWAYS_SAMPLER,
153+
}).getTracer('default');
154+
const processor = new BatchSpanProcessor(exporter, defaultBufferConfig);
155+
156+
// start but do not end spans
157+
for (let i = 0; i < defaultBufferConfig.bufferSize; i++) {
158+
const span = tracer.startSpan('spanName');
159+
processor.onStart(span as Span);
160+
}
161+
162+
setTimeout(() => {
163+
assert.strictEqual(exporter.getFinishedSpans().length, 0);
164+
// after the timeout, export should not have been called
165+
// because no spans are ended
166+
sinon.assert.notCalled(spy);
167+
done();
168+
}, defaultBufferConfig.bufferTimeout + 1000);
169+
170+
// no spans have been finished
171+
assert.strictEqual(exporter.getFinishedSpans().length, 0);
172+
clock.tick(defaultBufferConfig.bufferTimeout + 1000);
173+
174+
clock.restore();
175+
});
145176
});
146177
});

0 commit comments

Comments
 (0)
Please sign in to comment.