Skip to content

Commit

Permalink
add garbage collection to async resource map
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardoventurini committed Oct 16, 2024
1 parent 1f200cd commit bbfcdf2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
30 changes: 22 additions & 8 deletions async-interceptor.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
import async_hooks from 'node:async_hooks';

export const asyncResources = new Map();
// 50% of map limit
export const GC_LIMIT = Math.pow(2, 23);

export const AsyncResourceMap = new Map();

export const AsyncInterceptor = async_hooks.createHook({
init(asyncId, type, triggerAsyncId, resource) {
logResourceCreation(asyncId, type, triggerAsyncId, resource);
init(asyncId, type) {
logResourceCreation(asyncId, type);
},
});

function logResourceCreation(asyncId, type, triggerAsyncId, resource) {
function logResourceCreation(asyncId, type) {
const stack = (new Error()).stack.split('\n').slice(2).filter(line => {
return !['AsyncHook.init', 'node:internal/async_hooks'].some(fn => line.includes(fn));
}).join('\n');

if (!asyncResources.has(stack)) {
asyncResources.set(stack, { count: 0, types: new Set() });
if (AsyncResourceMap.size > GC_LIMIT) {
console.log('Meteor Perf: Garbage collecting async resources');
garbageCollectAsyncResources();
}

if (!AsyncResourceMap.has(stack)) {
AsyncResourceMap.set(stack, { count: 0, types: new Set() });
}

const resourceInfo = asyncResources.get(stack);
const resourceInfo = AsyncResourceMap.get(stack);
resourceInfo.count++;
resourceInfo.types.add(type);
}


function garbageCollectAsyncResources() {
AsyncResourceMap.forEach((info, stack) => {
if (info.count <= 1) {
AsyncResourceMap.delete(stack);
}
});
}
4 changes: 2 additions & 2 deletions save-output.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { asyncResources } from './async-interceptor';
import { AsyncResourceMap } from './async-interceptor';
import { StatDict } from './observer-monitor';
import path from 'node:path';
import fs from 'node:fs';
Expand All @@ -9,7 +9,7 @@ export function saveOutput() {
performance.mark('saveOutput-start');
let async_traces = []

asyncResources.forEach((info, stack) => {
AsyncResourceMap.forEach((info, stack) => {
if (info.count <= 1) {
return;
}
Expand Down

0 comments on commit bbfcdf2

Please sign in to comment.