Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 18b5cfb

Browse files
authored
chore(core): store cls contexts on a Map (#786)
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
1 parent 754b904 commit 18b5cfb

File tree

1 file changed

+7
-6
lines changed
  • packages/opencensus-core/src/internal

1 file changed

+7
-6
lines changed

packages/opencensus-core/src/internal/cls-ah.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import * as shimmer from 'shimmer';
2828

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

3434
// Create the hook.
@@ -137,13 +137,14 @@ function init(
137137
parentUid: number,
138138
parentHandle: {}
139139
) {
140-
contexts[uid] = current;
140+
contexts.set(uid, current);
141141
}
142142

143143
/** before is called just before the resource's callback is called. */
144144
function before(uid: number) {
145-
if (contexts[uid]) {
146-
current = contexts[uid];
145+
const maybeCurrent = contexts.get(uid);
146+
if (maybeCurrent !== undefined) {
147+
current = maybeCurrent;
147148
}
148149
}
149150

@@ -152,7 +153,7 @@ function before(uid: number) {
152153
* its entry in the map.
153154
*/
154155
function destroy(uid: number) {
155-
delete contexts[uid];
156+
contexts.delete(uid);
156157
}
157158

158159
export function createNamespace(): CLSNamespace {
@@ -161,7 +162,7 @@ export function createNamespace(): CLSNamespace {
161162

162163
export function destroyNamespace(): void {
163164
current = {};
164-
contexts = {};
165+
contexts = new Map();
165166
}
166167

167168
export function getNamespace(): CLSNamespace {

0 commit comments

Comments
 (0)