Skip to content

Commit

Permalink
[fix] add arbitrary limits to Trace tree to bound memory usage
Browse files Browse the repository at this point in the history
  • Loading branch information
jbunton-atlassian committed Feb 20, 2018
1 parent 1d4af88 commit 1672a02
Showing 1 changed file with 36 additions and 3 deletions.
39 changes: 36 additions & 3 deletions trace.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ function debug(msg) {
fs.writeSync(1, 'trace.js DEBUG ' + msg + '\n');
}

// Arbitrarily limit ourselves so we don't use up all memory on storing stack traces
const MAX_DESCENDANT_COUNT = 10;
const MAX_DESCENDANT_DEPTH_TRAVERSAL = 10;
const MAX_STACKS_TO_JOIN = 50;

const chain = require('stack-chain');
const asyncHook = require('async_hooks');

Expand Down Expand Up @@ -88,25 +93,36 @@ class Trace {
[asyncId, stack]
]);
this.descendants = [];
this.disabled = false;
}

recordDescendant(descendant) {
if (this.descendants.includes(descendant)) {
if (this.disabled || this.descendants.includes(descendant)) {
return;
}

this.descendants.push(descendant);

if (this.descendants.length >= MAX_DESCENDANT_COUNT) {
this.descendants = [];
this.disabled = true;
return;
}

for (const subDescendant of descendant.walk()) {
mergeIntoStackMap(subDescendant.stackMap, this.stackMap);
removeOldestFromStackMap(subDescendant.stackMap);
}
}

walk(visited=[this]) {
walk(visited=[this], depth=0) {
if (depth > MAX_DESCENDANT_DEPTH_TRAVERSAL) {
return;
}
for (const trace of this.descendants) {
if (!visited.includes(trace)) {
visited.push(trace);
trace.walk(visited);
trace.walk(visited, depth + 1);
}
}
return visited;
Expand All @@ -119,6 +135,19 @@ function mergeIntoStackMap(dest, source) {
}
}

function removeOldestFromStackMap(stackMap) {
if (stackMap.size < MAX_STACKS_TO_JOIN) {
return;
}

for (const key of sort(stackMap.keys())) {
if (stackMap.size < MAX_STACKS_TO_JOIN) {
return;
}
stackMap.delete(key);
}
}

function appendExtendedFrames(frames, trace) {
for (const asyncId of rsort(trace.stackMap.keys())) {
const newFrames = trace.stackMap.get(asyncId);
Expand All @@ -137,6 +166,10 @@ function appendUniqueFrames(frames, newFrames) {
frames.push(...newFrames);
}

function sort(iterator) {
return Array.from(iterator).sort((a, b) => a - b);
}

function rsort(iterator) {
return Array.from(iterator).sort((a, b) => b - a);
}
Expand Down

0 comments on commit 1672a02

Please sign in to comment.