Skip to content

Commit e777572

Browse files
committed
fix so that an ended span is never used as a parent
1 parent 4df2746 commit e777572

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

lib/instrumentation/index.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,8 @@ Instrumentation.prototype.currTx = function () {
9999
return this._runCtxMgr.active().tx || null
100100
}
101101
Instrumentation.prototype.currSpan = function () {
102-
const spanStack = this._runCtxMgr.active().spans
103-
if (spanStack.length === 0) {
104-
return null
105-
} else {
106-
return spanStack[spanStack.length - 1]
107-
}
102+
return this._runCtxMgr.active().currSpan()
108103
}
109-
// XXX unneeded?
110-
// Instrumentation.prototype.currParent = function () {
111-
// return this._runCtxMgr.active().topSpanOrTx()
112-
// }
113104

114105
Object.defineProperty(Instrumentation.prototype, 'ids', {
115106
get () {
@@ -287,7 +278,7 @@ Instrumentation.prototype.addEndedSpan = function (span) {
287278
}
288279

289280
const rc = this._runCtxMgr.active()
290-
if (rc.topSpanOrTx() === span) {
281+
if (rc.topSpan() === span) {
291282
// Replace the active run context with this span popped off the stack,
292283
// i.e. this span is no longer active.
293284
this._runCtxMgr.replaceActive(rc.exitSpan())
@@ -325,6 +316,7 @@ Instrumentation.prototype.startTransaction = function (name, ...args) {
325316
return tx
326317
}
327318

319+
// XXX !
328320
Instrumentation.prototype.endTransaction = function (result, endTime) {
329321
if (!this.currentTransaction) {
330322
this._agent.logger.debug('cannot end transaction - no active transaction found')

lib/run-context/BasicRunContextManager.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,25 @@ class RunContext {
4848
return !this.tx
4949
}
5050

51-
topSpanOrTx () {
51+
// Returns the currently active span, if any.
52+
//
53+
// Because the `startSpan()/endSpan()` API allows (a) affecting the current
54+
// run context and (b) out of order start/end, the "currently active span"
55+
// must skip over ended spans.
56+
currSpan () {
57+
for (let i = this.spans.length - 1; i >= 0; i--) {
58+
const span = this.spans[i]
59+
if (!span.ended) {
60+
return span
61+
}
62+
}
63+
return null
64+
}
65+
66+
// This returns the top span in the span stack (even if it is ended).
67+
topSpan () {
5268
if (this.spans.length > 0) {
5369
return this.spans[this.spans.length - 1]
54-
} else if (this.tx) {
55-
return this.tx
5670
} else {
5771
return null
5872
}
@@ -62,6 +76,12 @@ class RunContext {
6276
// stack.
6377
enterSpan (span) {
6478
const newSpans = this.spans.slice()
79+
80+
// Any ended spans at the top of the stack are cruft -- remove them.
81+
while (newSpans.length > 0 && newSpans[newSpans.length - 1].ended) {
82+
newSpans.pop()
83+
}
84+
6585
newSpans.push(span)
6686
return new RunContext(this.tx, newSpans)
6787
}

0 commit comments

Comments
 (0)