Skip to content

Commit 3ad8c59

Browse files
authored
fix: Fixed transaction-shim to properly create new transactions when the existing transaction is not active (#2912)
1 parent 4a30d5c commit 3ad8c59

File tree

2 files changed

+74
-7
lines changed

2 files changed

+74
-7
lines changed

lib/shim/transaction-shim.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,13 @@ function _makeNestedTransWrapper(shim, func, name, spec) {
372372
}
373373

374374
let context = shim.tracer.getContext()
375+
let transaction = shim.tracer.getTransaction()
375376

376377
// Only create a new transaction if we either do not have a current
377378
// transaction _or_ the current transaction is not of the type we want.
378-
if (!context?.transaction || spec.type !== context?.transaction?.type) {
379+
if (!transaction || spec.type !== transaction?.type) {
379380
shim.logger.trace('Creating new nested %s transaction for %s', spec.type, name)
380-
const transaction = new Transaction(shim.agent)
381+
transaction = new Transaction(shim.agent)
381382
transaction.type = spec.type
382383
context = context.enterTransaction(transaction)
383384
}
@@ -405,10 +406,11 @@ function _makeNestedTransWrapper(shim, func, name, spec) {
405406
*/
406407
function _makeTransWrapper(shim, func, name, spec) {
407408
return function transactionWrapper() {
408-
// Don't nest transactions, reuse existing ones!
409409
let context = shim.tracer.getContext()
410-
const existingTransaction = context.transaction
410+
// Don't nest transactions, reuse existing ones!
411+
const existingTransaction = shim.tracer.getTransaction()
411412
if (!shim.agent.canCollectData() || existingTransaction) {
413+
shim.logger.trace('Transaction %s exists, not creating new transaction %s for %s', existingTransaction?.id, spec.type, name)
412414
return func.apply(this, arguments)
413415
}
414416

test/unit/shim/transaction-shim.test.js

+68-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const helper = require('../../lib/agent_helper')
1212
const { TransactionSpec } = require('../../../lib/shim/specs')
1313
const TransactionShim = require('../../../lib/shim/transaction-shim')
1414
const notRunningStates = ['stopped', 'stopping', 'errored']
15+
const sinon = require('sinon')
1516

1617
/**
1718
* Creates CAT headers to be used in handleMqTracingHeaders
@@ -220,15 +221,16 @@ test('TransactionShim', async function (t) {
220221

221222
await t.test('should not create a nested transaction when `spec.nest` is false', function (t) {
222223
const { shim } = t.nr
224+
sinon.stub(shim.logger, 'trace')
223225
let webTx = null
224226
let bgTx = null
225227
let webCalled = false
226228
let bgCalled = false
227-
const bg = shim.bindCreateTransaction(function () {
229+
const bg = shim.bindCreateTransaction(function bgTxFn() {
228230
bgCalled = true
229231
bgTx = shim.tracer.getTransaction()
230232
}, new TransactionSpec({ type: shim.BG }))
231-
const web = shim.bindCreateTransaction(function () {
233+
const web = shim.bindCreateTransaction(function webTxFn() {
232234
webCalled = true
233235
webTx = shim.tracer.getTransaction()
234236
bg()
@@ -237,7 +239,51 @@ test('TransactionShim', async function (t) {
237239
web()
238240
assert.equal(webCalled, true)
239241
assert.equal(bgCalled, true)
240-
assert.equal(webTx, bgTx)
242+
assert.equal(webTx.id, bgTx.id)
243+
assert.deepEqual(shim.logger.trace.args, [
244+
['Wrapping nodule itself (%s).', 'bgTxFn'],
245+
['Wrapping nodule itself (%s).', 'webTxFn'],
246+
['Creating new %s transaction for %s', 'web', 'webTxFn'],
247+
['Applying segment %s', 'ROOT'],
248+
[
249+
'Transaction %s exists, not creating new transaction %s for %s',
250+
bgTx.id,
251+
'bg',
252+
'bgTxFn'
253+
]
254+
])
255+
})
256+
257+
await t.test('should create a new transaction when `spec.nest` is false and current transaction is not active', function (t) {
258+
const { shim } = t.nr
259+
sinon.stub(shim.logger, 'trace')
260+
let webTx = null
261+
let bgTx = null
262+
let webCalled = false
263+
let bgCalled = false
264+
const bg = shim.bindCreateTransaction(function bgTxFn() {
265+
bgCalled = true
266+
bgTx = shim.tracer.getTransaction()
267+
}, new TransactionSpec({ type: shim.BG }))
268+
const web = shim.bindCreateTransaction(function webTxFn() {
269+
webCalled = true
270+
webTx = shim.tracer.getTransaction()
271+
webTx.end()
272+
bg()
273+
}, new TransactionSpec({ type: shim.WEB }))
274+
275+
web()
276+
assert.equal(webCalled, true)
277+
assert.equal(bgCalled, true)
278+
assert.notEqual(webTx.id, bgTx.id)
279+
assert.deepEqual(shim.logger.trace.args, [
280+
['Wrapping nodule itself (%s).', 'bgTxFn'],
281+
['Wrapping nodule itself (%s).', 'webTxFn'],
282+
['Creating new %s transaction for %s', 'web', 'webTxFn'],
283+
['Applying segment %s', 'ROOT'],
284+
['Creating new %s transaction for %s', 'bg', 'bgTxFn'],
285+
['Applying segment %s', 'ROOT']
286+
])
241287
})
242288

243289
for (const agentState of notRunningStates) {
@@ -319,6 +365,25 @@ test('TransactionShim', async function (t) {
319365
}
320366
})
321367

368+
await t.test('should not nest transaction if first transaction is inactive and same type', function (t) {
369+
const { shim } = t.nr
370+
const transactions = []
371+
const web = shim.bindCreateTransaction(function (cb) {
372+
const tx = shim.tracer.getTransaction()
373+
transactions.push(tx)
374+
tx.end()
375+
if (cb) {
376+
cb()
377+
}
378+
}, new TransactionSpec({ type: shim.WEB, nest: true }))
379+
380+
const web2 = shim.bindCreateTransaction(function () {
381+
transactions.push(shim.tracer.getTransaction())
382+
}, new TransactionSpec({ type: shim.WEB, nest: true }))
383+
web(web2)
384+
assert.notEqual(transactions[0].id, transactions[1].id)
385+
})
386+
322387
for (const agentState of notRunningStates) {
323388
await t.test(`should not create transaction when agent state is ${agentState}`, (t) => {
324389
const { agent, shim } = t.nr

0 commit comments

Comments
 (0)