Skip to content

Instantly share code, notes, and snippets.

@Istar-Eldritch
Last active November 1, 2018 18:26
Show Gist options
  • Save Istar-Eldritch/5fb7f44ff16714f4707f78e091d634c6 to your computer and use it in GitHub Desktop.
Save Istar-Eldritch/5fb7f44ff16714f4707f78e091d634c6 to your computer and use it in GitHub Desktop.
Trampolining "memory leak" on ES6 recursive promise resolve chain.
const promiseYoullWork = () => Promise.resolve();
async function job(todo: number, iterations: number = 0): Promise<number> {
// Print memory consumption of the process every 10k iterations
if (iterations % 10000 === 0) {
const memUsage = process.memoryUsage();
const mem = (memUsage.heapTotal / 1024 / 1024);
console.log(`i: ${iterations / 1000}k`, `mem: ${Math.round(mem * 100) / 100} Mb`);
}
if (iterations === todo) {
return iterations;
} else {
await promiseYoullWork(/* Request to the database */);
return job(todo, iterations + 1);
}
}
job(1000000)
.then((iterations) => {
console.log(`Finished after ${iterations} iterations`);
})
.catch(console.error);
interface FT<I, O> extends Function {
(...args: I[]): O;
}
interface FN<I, O> extends FT<I, Promise<FN<I, O> | O>> {}
function trampolineP<I, O>(f: FN<I, O>): (...args: any[]) => Promise<O> {
return async function _trampoline(/*arguments*/): Promise<O> {
let result = await f.apply(f, Object.values(arguments));
while (result instanceof Function) {
result = await result();
}
return result;
};
}
const promiseYoullWork = () => Promise.resolve();
async function job(todo: number, iterations: number = 0): Promise<any> {
// Print memory consumption of the process every 10k iterations
if (iterations % 10000 === 0) {
const memUsage = process.memoryUsage();
const mem = (memUsage.heapTotal / 1024 / 1024);
console.log(`i: ${iterations / 1000}k`, `mem: ${Math.round(mem * 100) / 100} Mb`);
}
if (iterations >= todo) {
return iterations;
} else {
await promiseYoullWork(/* Request to the database */);
return () => job(todo, iterations + 1);
}
}
const trampolinedJob = trampolineP(job);
trampolinedJob(1000000)
.then((iterations: any) => {
console.log(`Finished after ${iterations} iterations`);
})
.catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment