From c565a851a36ac9b0b5121d97604d6a8e2c5acaa4 Mon Sep 17 00:00:00 2001 From: Bryan English Date: Fri, 8 Jan 2021 11:19:56 -0500 Subject: [PATCH] Call options fn on each invocation in tracer.wrap (#1191) Because the options variable in tracer.wrap was being re-assigned, options functions were only being executing a single time, and then the same result would be cached. This is fixed by using a variable local to the function invocation. Fixes #1181 --- packages/dd-trace/src/tracer.js | 11 ++++++----- packages/dd-trace/test/tracer.spec.js | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/dd-trace/src/tracer.js b/packages/dd-trace/src/tracer.js index 79d6f233e9..14a43630ce 100644 --- a/packages/dd-trace/src/tracer.js +++ b/packages/dd-trace/src/tracer.js @@ -69,11 +69,12 @@ class DatadogTracer extends Tracer { const tracer = this return function () { - if (typeof options === 'function' && typeof fn === 'function') { - options = options.apply(this, arguments) + let optionsObj = options + if (typeof optionsObj === 'function' && typeof fn === 'function') { + optionsObj = optionsObj.apply(this, arguments) } - if (options.orphanable === false && !tracer.scope().active()) { + if (optionsObj.orphanable === false && !tracer.scope().active()) { return fn.apply(this, arguments) } @@ -82,7 +83,7 @@ class DatadogTracer extends Tracer { if (typeof cb === 'function') { const scopeBoundCb = tracer.scope().bind(cb) - return tracer.trace(name, options, (span, done) => { + return tracer.trace(name, optionsObj, (span, done) => { arguments[lastArgId] = function (err) { done(err) return scopeBoundCb.apply(this, arguments) @@ -91,7 +92,7 @@ class DatadogTracer extends Tracer { return fn.apply(this, arguments) }) } else { - return tracer.trace(name, options, () => fn.apply(this, arguments)) + return tracer.trace(name, optionsObj, () => fn.apply(this, arguments)) } } } diff --git a/packages/dd-trace/test/tracer.spec.js b/packages/dd-trace/test/tracer.spec.js index d99b8147cf..1ce275635c 100644 --- a/packages/dd-trace/test/tracer.spec.js +++ b/packages/dd-trace/test/tracer.spec.js @@ -383,14 +383,17 @@ describe('Tracer', () => { }) }) - it('should accept an options function', () => { + it('should accept an options function, invoked on every invocation of the wrapped function', () => { const it = {} + let invocations = 0 + function options (foo, bar) { + invocations++ expect(this).to.equal(it) expect(foo).to.equal('hello') expect(bar).to.equal('goodbye') - return { tags: { sometag: 'somevalue' } } + return { tags: { sometag: 'somevalue', invocations } } } const fn = tracer.wrap('name', options, function () {}) @@ -400,7 +403,13 @@ describe('Tracer', () => { fn.call(it, 'hello', 'goodbye') expect(tracer.trace).to.have.been.calledWith('name', { - tags: { sometag: 'somevalue' } + tags: { sometag: 'somevalue', invocations: 1 } + }) + + fn.call(it, 'hello', 'goodbye') + + expect(tracer.trace).to.have.been.calledWith('name', { + tags: { sometag: 'somevalue', invocations: 2 } }) })