Skip to content

Commit

Permalink
chore(core): store cls contexts on a Map
Browse files Browse the repository at this point in the history
Node.js v12 is affected by a V8 regression where many
insert/deletes on a POJO will trigger an undefined state on V8, leading
to a huge performance regression which can cause each insert/delete
operations on that object to take hundreds of times more. The Map
structure is not affected by this performance regression (and is
recommended by engine developers to deal with large key/value stores).

Contexts on cls-ah are stored on a POJO, and since inserts/deletes
happen often (they are triggered by async_hooks on init and destroy),
applications with high RPS or with high amount of async operations will
hit the threshold, turning the regression on and leading to a huge
performance overhead on each new async operation. Changing to a Map will
avoid that issue.

Ref: nodejs/node#31961
  • Loading branch information
mmarchini committed Mar 27, 2020
1 parent 754b904 commit 42a4b7a
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions packages/opencensus-core/src/internal/cls-ah.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import * as shimmer from 'shimmer';

const WRAPPED = Symbol('context_wrapped');
/** A map of AsyncResource IDs to Context objects. */
let contexts: { [asyncId: number]: Context } = {};
let contexts: Map<number, Context> = new Map();
let current: Context = {};

// Create the hook.
Expand Down Expand Up @@ -137,13 +137,14 @@ function init(
parentUid: number,
parentHandle: {}
) {
contexts[uid] = current;
contexts.set(uid, current);
}

/** before is called just before the resource's callback is called. */
function before(uid: number) {
if (contexts[uid]) {
current = contexts[uid];
const maybeCurrent = contexts.get(uid);
if (maybeCurrent !== undefined) {
current = maybeCurrent;
}
}

Expand All @@ -152,7 +153,7 @@ function before(uid: number) {
* its entry in the map.
*/
function destroy(uid: number) {
delete contexts[uid];
contexts.delete(uid);
}

export function createNamespace(): CLSNamespace {
Expand All @@ -161,7 +162,7 @@ export function createNamespace(): CLSNamespace {

export function destroyNamespace(): void {
current = {};
contexts = {};
contexts = new Map();
}

export function getNamespace(): CLSNamespace {
Expand Down

0 comments on commit 42a4b7a

Please sign in to comment.