-
Notifications
You must be signed in to change notification settings - Fork 71
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
fix: workaround leak through promise resolvers #1222
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could alternately move this into ses
as a taming of the existing Promise.race
. It would only be a slight feature creep.
Why not just as a separate "vetted shim" package, loaded by |
That’s even better. |
84d12ac
to
2cc9f3e
Compare
Updated to use a vetted shim approach, and reverted the explicit uses to rely on the shim. Also updated the implementation to follow the spec more closely. It'd be nice to test against test262, but I don't believe we have the infra for that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not done yet. Just giving you bits as they occur to minimize latency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not do a thorough review of memo-race.js . But nothing seemed wrong, and you already have @kriskowal 's approval. I'll defer to that. Please proceed.
Avoids leaking the promise through stray resolvers
0377da0
to
219e49d
Compare
Added a blurb to |
The investigation into Agoric/agoric-sdk#5507 lead us into discovering a leak caused by promises, in particular when using
Promise.race
with a long pending promise. The root cause really seem that the promise resolve functions hold onto the promise strongly (instead of just an internal record representing the reactions registered on the promise), and through that, the result of said promise.Promise.race
is implemented as adding the result's promise's resolver functions to each of the contenders reactions, causing the long pending promise to keep the raced result alive.This PR re-implements
Promise.race
based on the solution in nodejs/node#17469 (comment). It also updatesmakePromiseKit
to return resolvers that will sever their hold on the original resolvers (and thus the promise) once called. That latter approach, while simpler, is not sufficient forPromise.race
as reactions would keep queueing on the long pending promise (engines are not sufficiently smart to realize a reaction is a native resolver that has become inert).Finally it installs the new race implementation as a
Promise.race
vetted shim in@endo/init
.(I'm half considering re-writing promises in userland with proper support for short-circuiting, which would avoid most of these issues, but the few spec places creating primordial promises would damper that. A long term solution might be to rewrite the spec with proper short-circuiting, maybe as part of tc39/proposal-faster-promise-adoption)