Skip to content

Commit 01ea223

Browse files
authored
Only intercept enterWith() for span-carrying legacy storage (#7858)
1 parent a498993 commit 01ea223

2 files changed

Lines changed: 23 additions & 20 deletions

File tree

packages/dd-trace/src/profiling/profilers/wall.js

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,33 +58,30 @@ function ensureChannelsActivated (asyncContextFrameEnabled) {
5858
if (channelsActivated) return
5959

6060
const shimmer = require('../../../../datadog-shimmer')
61-
const asyncHooks = require('async_hooks')
6261

63-
// When using AsyncContextFrame to store sample context, we do not need to use
64-
// async_hooks.createHook to create a "before" callback anymore.
65-
if (!asyncContextFrameEnabled) {
66-
const { createHook } = asyncHooks
67-
beforeCh = dc.channel('dd-trace:storage:before')
68-
createHook({ before: () => beforeCh.publish() }).enable()
69-
}
70-
71-
const { AsyncLocalStorage } = asyncHooks
72-
73-
// We need to instrument AsyncLocalStorage.enterWith() both with and without AsyncContextFrame.
62+
// We need to instrument enterWith() on the legacy storage — that's the storage
63+
// carrying span data and the only one the profiler cares about.
64+
const legacyStorage = storage('legacy')
7465
let inRun = false
75-
shimmer.wrap(AsyncLocalStorage.prototype, 'enterWith', function (original) {
76-
return function (...args) {
77-
const retVal = original.apply(this, args)
66+
shimmer.wrap(legacyStorage, 'enterWith', function (original) {
67+
return function (store) {
68+
const retVal = original.call(this, store)
7869
if (!inRun) enterCh.publish()
7970
return retVal
8071
}
8172
})
8273

83-
// We only need to instrument AsyncLocalStorage.run() when not using AsyncContextFrame.
84-
// AsyncContextFrame-based implementation of AsyncLocalStorage.run() delegates
85-
// to AsyncLocalStorage.enterWith() so it doesn't need to be separately instrumented.
74+
// When not using AsyncContextFrame, we need additional instrumentation.
8675
if (!asyncContextFrameEnabled) {
87-
shimmer.wrap(AsyncLocalStorage.prototype, 'run', function (original) {
76+
// We need async_hooks.createHook to create a "before" callback.
77+
const { createHook } = require('async_hooks')
78+
beforeCh = dc.channel('dd-trace:storage:before')
79+
createHook({ before: () => beforeCh.publish() }).enable()
80+
81+
// In ACF-based implementation run() delegates to enterWith() so it doesn't
82+
// need to be separately instrumented. in non-ACF implementation run()
83+
// doesn't delegate to enterWith(), so separate instrumentation is necessary.
84+
shimmer.wrap(legacyStorage, 'run', function (original) {
8885
return function (store, callback, ...args) {
8986
const wrappedCb = shimmer.wrapFunction(callback, cb => function (...args) {
9087
inRun = false

packages/dd-trace/test/profiling/profilers/wall.spec.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,13 @@ describe('profilers/native/wall', () => {
323323

324324
WallProfiler = proxyquire('../../../src/profiling/profilers/wall', {
325325
'@datadog/pprof': localPprof,
326-
'../../../../datadog-core': { storage: () => ({ getStore: () => currentStore }) },
326+
'../../../../datadog-core': {
327+
storage: () => ({
328+
getStore: () => currentStore,
329+
enterWith () {},
330+
run (store, cb, ...args) { return cb(...args) },
331+
}),
332+
},
327333
})
328334
})
329335

0 commit comments

Comments
 (0)