Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Removed legacy context manager #2404

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 0 additions & 38 deletions .github/workflows/versioned-coverage.yml

This file was deleted.

6 changes: 0 additions & 6 deletions documentation/feature-flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ Any prerelease flags can be enabled or disabled in your agent config by adding a
* Description: Now that `new_promise_tracking` is the default async context tracking behavior in the agent, `unresolved_promise_cleanup` is enabled by default. Disabling it can help with performance of agent when an application creates many promises.
* **WARNING**: If you set `unresolved_promise_cleanup` to `false`, failure to resolve all promises in your application will result in memory leaks even if those promises are garbage collected.

#### legacy_context_manager
* Enabled by default: `false`
* Configuration: `{ feature_flag: { legacy_context_manager: true|false }}`
* Environment Variable: `NEW_RELIC_FEATURE_FLAG_LEGACY_CONTEXT_MANAGER`
* Description: The legacy context manager was replaced by AsyncLocalContextManager for async context propagation. If your application is not recording certain spans or creating orphaned data, you may want to enable this older context manager. Enabling this feature flag may increase the agent's use of memory and CPU.

#### kakfajs_instrumentation
* Enabled by default: `false`
* Configuration: `{ feature_flag: { kafkajs_instrumentation: true|false }}`
Expand Down
11 changes: 0 additions & 11 deletions lib/context-manager/create-context-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ const logger = require('../logger')
* the current configuration.
*/
function createContextManager(config) {
if (config.feature_flag.legacy_context_manager) {
return createLegacyContextManager(config)
}

return createAsyncLocalContextManager(config)
}

Expand All @@ -30,11 +26,4 @@ function createAsyncLocalContextManager(config) {
return new AsyncLocalContextManager(config)
}

function createLegacyContextManager(config) {
logger.info('Using LegacyContextManager')

const LegacyContextManager = require('./legacy-context-manager')
return new LegacyContextManager(config)
}

module.exports = createContextManager
66 changes: 0 additions & 66 deletions lib/context-manager/legacy-context-manager.js

This file was deleted.

3 changes: 1 addition & 2 deletions lib/feature_flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ exports.prerelease = {
reverse_naming_rules: false,
undici_async_tracking: true,
unresolved_promise_cleanup: true,
legacy_context_manager: false,
kafkajs_instrumentation: false
}

Expand Down Expand Up @@ -43,4 +42,4 @@ exports.released = [
]

// flags that are no longer used for unreleased features
exports.unreleased = ['unreleased']
exports.unreleased = ['unreleased', 'legacy_context_manager']
132 changes: 0 additions & 132 deletions lib/instrumentation/core/async-hooks.js

This file was deleted.

5 changes: 0 additions & 5 deletions lib/instrumentation/core/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

'use strict'

const asyncHooks = require('./async-hooks')
const symbols = require('../../symbols')

module.exports = initialize
Expand Down Expand Up @@ -63,8 +62,4 @@ function initialize(agent, nodule, name, shim) {
return original.apply(this, arguments)
}
}

// This will initialize the most optimal native-promise instrumentation that
// we have available.
asyncHooks(agent, shim)
}
73 changes: 1 addition & 72 deletions lib/instrumentation/core/timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,10 @@ const Timers = require('timers')

module.exports = initialize

function initialize(agent, timers, _moduleName, shim) {
const isLegacyContext = agent.config.feature_flag.legacy_context_manager

if (isLegacyContext) {
instrumentProcessMethods(shim, process)
instrumentSetImmediate(shim, [timers, global])
}

function initialize(_agent, timers, _moduleName, shim) {
instrumentTimerMethods(shim, [timers, global])
}

/**
* Sets up instrumentation for setImmediate on both timers and global.
*
* We do not want to create segments for setImmediate calls,
* as the object allocation may incur too much overhead in some situations
*
* @param {Shim} shim instance of shim
* @param {Array<Timers,global>} pkgs array with references to timers and global
*/
function instrumentSetImmediate(shim, pkgs) {
pkgs.forEach((nodule) => {
if (shim.isWrapped(nodule.setImmediate)) {
return
}

shim.wrap(nodule, 'setImmediate', function wrapSetImmediate(shim, fn) {
return function wrappedSetImmediate() {
const segment = shim.getActiveSegment()
if (!segment) {
return fn.apply(this, arguments)
}

const args = shim.argsToArray.apply(shim, arguments, segment)
shim.bindSegment(args, shim.FIRST)

return fn.apply(this, args)
}
})

copySymbols(shim, nodule, 'setImmediate')
})
}

/**
* Sets up instrumentation for setTimeout, setInterval and clearTimeout
* on timers and global.
Expand Down Expand Up @@ -107,37 +67,6 @@ function recordAsynchronizers(shim, _fn, name) {
return new RecorderSpec({ name: 'timers.' + name, callback: shim.FIRST })
}

/**
* Instruments core process methods: nextTick, _nextDomainTick, _tickDomainCallback
* Note: This does not get registered when the context manager is async local
*
* @param {Shim} shim instance of shim
* @param {process} process global process object
*/
function instrumentProcessMethods(shim, process) {
const processMethods = ['nextTick', '_nextDomainTick', '_tickDomainCallback']

shim.wrap(process, processMethods, function wrapProcess(shim, fn) {
return function wrappedProcess() {
const segment = shim.getActiveSegment()
if (!segment) {
return fn.apply(this, arguments)
}

// Manual copy because helper methods add significant overhead in some usages
const len = arguments.length
const args = new Array(len)
for (let i = 0; i < len; ++i) {
args[i] = arguments[i]
}

shim.bindSegment(args, shim.FIRST, segment)

return fn.apply(this, args)
}
})
}

/**
* Copies the symbols from original setTimeout and setInterval onto the wrapped functions
*
Expand Down
Loading
Loading