-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aggressive memory leak in Repeater.race #65
Comments
Initial investigation shows that calling Promise.race with an iteration and the stop promise (or any promise which does not settle) spawns a promise reaction for the stop promise, and this reaction retains the paired iteration. This is a consequence of the implementation of Part of me wonders if Relevant issues: |
Here’s a reproduction of the leak without repeaters: async function randomString(): Promise<string> {
await new Promise((resolve) => setTimeout(resolve, 1));
return crypto.randomBytes(10000).toString("hex")
}
async function *createStrings() {
while (true) {
yield randomString();
}
}
(async function main() {
let i = 0;
let iteration: IteratorResult<string>;
const iterator = createStrings();
const pending: Promise<never> = new Promise(() => {});
do {
iteration = await Promise.race([pending, iterator.next()]);
if (i++ % 1000 === 0) {
const usage = process.memoryUsage();
const rssMiB = Math.round(usage.rss / (1024 ** 2) * 100) / 100;
console.log(`Resident Set: ${rssMiB} MiB`);
}
} while (!iteration.done);
})(); |
Reported by @elderapo.
When
Repeater.race
is called with an iterator and a promise which doesn’t settle, memory usage grows until the process crashes.Reproduction:
This will log an increasing resident set size until the process runs out of memory. It seems to be exacerbated by what is passed through the iterator which is racing the
stop
promise.The text was updated successfully, but these errors were encountered: