-
Notifications
You must be signed in to change notification settings - Fork 108
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
Add support for timers/promises module from nodejs #495
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.
Very solid work! Love the implementation and the tests. Just had a minor comment. You can see what you think of it before I approve. It's just a minor quibble.
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.
There are some leaks in the signal (e.g. we don't remove the event listener when fake timers are uninstalled) but generally that's fine for the first version so lgtm.
Good note about the removal of event listeners. When I do any development on Sinon projects, I tend to make use of the watch feature of the test runner. That's where stuff like not cleaning up properly tends to show itself. If it's not too much problem, I'd like to see that being done. |
Sure, I can take a look at it. Just so we're on the same page, we're talking about the scenario where while a timer is running, an abort signal has been passed, and the clock is uninstalled before the timer fires, leading to it never firing and the therefore the abort signal listener never being removed? This is something I have missed, and the listeners should absolutely be removed in that scenario, but for what it's worth I don't think it would lead to memory leaks while running tests in watch mode. As long as no references remain to the abort signal, it should be garbage collected and the event listener along with it. As to how to solve this, I would like a second opinion on how to approach it. The way I see it this would require something akin to an |
You know what, I don't have available mental capacity (or time) at the moment to dig deeply into this, and if it really isn't an issue in practice, then I have no issues merging this now. There's always room for another PR later, if you find a nice way that isn't too complicated. |
Any idea when a new release will be cut with this change? |
Thanks for the reminder :) |
References can remain to the signal (e.g. the signal is the result of It's fine for it to happen at a follow up PR. Generally you did cleanup a lot better than I expected in this PR in the first place and it's a relatively small miss. I review a lot of AbortSignal library code so this is a compliment :)
We keep a list/map or all signal and event listeners associated with the clock instance and when the clock is uninstalled we call that? // Somewhere when an event listener is added
signal.addEventListener('abort', listener, options);
clock.listners.push({ signal, listener });
// In uninstall
clock.listeners.forEach(({ signal, listener }) => signal.removeEventListener(listener)) |
Ohh, I see. Yeah then it's definitely something that would be good to get fixed before a release.
Thanks for the input. I'll proceed with that kind of a solution and make a separate PR. |
@u873838 Thanks to White Autumns swift second PR this is already out. |
Purpose (TL;DR)
Fix issue #469 by implementing promise-based wrappers around setTimeout, setImmediate, and setInterval.
Solution
This PR takes a similar approach to #467 by @swenzel-arc of detecting the availability of the
timers/promises
module by attempting to import it and then overwriting the functions on the import object, which should be the same object users have, given they do not mess with the module cache. Like the aforementioned PR, the functions are only overwritten when callinginstall()
on theglobalObject
.Limitations
AbortSignal
, the error thrown is not the same as the one thrown by node. This is due to theAbortError
error being publicly available. See this issue.timers/promises
module as they are marked as experimental.