| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
For web compatibility this allows timers to be stored as the key of an Object property and be passed back to corresponding method to clear the timer.
| // Schedule or re-schedule a timer. | ||
| // The item must have been enroll()'d first. | ||
| const active = exports.active = function(item) { | ||
| KNOWN_TIMERS[item[async_id_symbol]] = item; |
There was a problem hiding this comment.
Can we do the caching in [@@toPrimitive]()? I doubt this is a very frequently used feature, so it might be good if we could avoid the storage overhead for the common case?
Sorry, something went wrong.
There was a problem hiding this comment.
seems fine to change that.
Sorry, something went wrong.
There was a problem hiding this comment.
not sure how we could easily avoid the delete though when clearing without doing some funny stuff. the cache should swap into dictionary mode really fast though.
Sorry, something went wrong.
|
Did you check benchmarks? |
Sorry, something went wrong.
|
@mscdex I did not. I would be very surprised if it has any significant impact. |
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM if the benchmarks are happy
This is semver-minor, right? Should we document this?
Sorry, something went wrong.
| exports.clearInterval = function(timer) { | ||
| if (typeof timer === 'number' || typeof timer === 'string') { | ||
| if (timer in KNOWN_TIMERS) { | ||
| clearInterval(KNOWN_TIMERS[timer]); |
There was a problem hiding this comment.
I think we may want to avoid accessing global.clearInterval here … maybe doing something like we do for clearTimeout, i.e. const clearInterval = exports.clearInterval = … is a good idea here too?
Sorry, something went wrong.
There was a problem hiding this comment.
ah yes, that would be a bug if that happened. I'm not 100% sure on why these functions are not named looking at them...
Sorry, something went wrong.
|
I ran ./node benchmark/run.js timers but am not seeing anything changing within margin of error. |
Sorry, something went wrong.
|
@bmeck You may already know this, but in case not: If you have a binary compiled from master called node-old and a binary compiled with your changes called node-new, you can have it do the statistical computation for you with something like: node benchmark/compare.js --old node-old --new node-new timers > my-benchmark.csv...followed by... cat my-benchmark.csv | Rscript compare.RSee https://github.com/nodejs/node/blob/master/doc/guides/writing-and-running-benchmarks.md#comparing-nodejs-versions for more information. |
Sorry, something went wrong.
|
(Edited above to include correct command...) |
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, something went wrong.
|
|
||
| ### timeout[Symbol.toPrimitive]() | ||
|
|
||
| When coercing a `Timeout` to a primitive, a primitive will be generated that can be used with the appropriate function that can be used to clear the `Timeout`. This allows enhanced compatibility with browser `setTimeout`, and `setInterval` implementations. |
There was a problem hiding this comment.
Nit: Please wrap at 80 characters :)
Sorry, something went wrong.
There was a problem hiding this comment.
fixed
Sorry, something went wrong.
| const clearInterval = exports.clearInterval = function(timer) { | ||
| if (typeof timer === 'number' || typeof timer === 'string') { | ||
| if (timer in KNOWN_TIMERS) { | ||
| clearInterval(KNOWN_TIMERS[timer]); |
There was a problem hiding this comment.
Would timer = KNOWN_TIMERS[timer] work? This would avoid a recursion.
Sorry, something went wrong.
There was a problem hiding this comment.
fixed
Sorry, something went wrong.
|
|
||
| ### timeout[Symbol.toPrimitive]() | ||
|
|
||
| When coercing a `Timeout` to a primitive, a primitive will be generated that can be used with the appropriate function that can be used to clear the `Timeout`. This allows enhanced compatibility with browser `setTimeout`, and `setInterval` implementations. |
There was a problem hiding this comment.
Wrap at 80 cols.
Sorry, something went wrong.
There was a problem hiding this comment.
fixed
Sorry, something went wrong.
|
|
||
| When coercing a `Timeout` to a primitive, a primitive will be generated that can be used with the appropriate function that can be used to clear the `Timeout`. This allows enhanced compatibility with browser `setTimeout`, and `setInterval` implementations. | ||
|
|
||
| Returns a `number`. |
There was a problem hiding this comment.
Put
* Returns: {integer}right below the heading.
Sorry, something went wrong.
There was a problem hiding this comment.
fixed
Sorry, something went wrong.
| const unrefedLists = Object.create(null); | ||
|
|
||
| const KNOWN_TIMERS = Object.create(null); | ||
|
|
There was a problem hiding this comment.
Extraneous line.
Sorry, something went wrong.
There was a problem hiding this comment.
fixed
Sorry, something went wrong.
| return true; | ||
| } | ||
|
|
||
| Timeout.prototype[Symbol.toPrimitive] = function() { |
There was a problem hiding this comment.
Why @@toPrimitive rather than valueOf?
Sorry, something went wrong.
There was a problem hiding this comment.
see https://codepen.io/bradleymeck/pen/eMMpdR?editors=0012 , .valueOf is not safe for using as a key. toPrimitive handles both string and number coercion.
Sorry, something went wrong.
|
There's one significant drop showing in the benchmark CI:
I guess we have to make a call deciding whether we're okay with that? |
Sorry, something went wrong.
There was a problem hiding this comment.
-1 if we're going to see a performance regression like that
Sorry, something went wrong.
|
It is probably from the uncondition delete in the cancel. We could replace timer.close when toPrimitive is called and make that more conditional at the cost of some odd things possibly showing up if people replace timer.close with a custom function and don't expect us to wrap it. I'll munge with this a bit and see if we can fix up that cliff. Not sure why my test wasn't showing it. |
Sorry, something went wrong.
| delete KNOWN_TIMERS[this[async_id_symbol]]; | ||
| this.close = $close; | ||
| this.close(); | ||
| } |
There was a problem hiding this comment.
This won't pass linting due to missing semicolon. Also, can the function be factored out?
Sorry, something went wrong.
There was a problem hiding this comment.
fixed / it cannot be factored out since it closes over $close.
Sorry, something went wrong.
There was a problem hiding this comment.
$close is effectively always equal to Timeout.prototype.close, right?
Sorry, something went wrong.
There was a problem hiding this comment.
since it is public and mutable, that is not certain.
Sorry, something went wrong.
There was a problem hiding this comment.
@bmeck I think it’s fine to just ignore that. You could still run into it anyway, when .close is changed after the [@@toPrimitive]() call…
Sorry, something went wrong.
There was a problem hiding this comment.
if they replace it they are probably wrapping it, I'm already ignoring all the ways to avoid getter/setters but don't feel comfortable with completely removing .close this seems like one of the metrics people could be profiling handle lifetimes.
Sorry, something went wrong.
| }; | ||
|
|
||
| exports.clearInterval = function(timer) { | ||
| const clearInterval = exports.clearInterval = function(timer) { |
There was a problem hiding this comment.
Why the addition of clearInterval variable? Doesn't seem used anywhere.
Sorry, something went wrong.
There was a problem hiding this comment.
was added in e32b969 as a bug fix to previous iteration
Sorry, something went wrong.
| if (timer in KNOWN_TIMERS) { | ||
| timer = KNOWN_TIMERS[timer]; | ||
| } | ||
| else { |
There was a problem hiding this comment.
This fails linting.
Sorry, something went wrong.
There was a problem hiding this comment.
fixed
Sorry, something went wrong.
|
@mscdex with the most change can you recheck your perf concerns? |
Sorry, something went wrong.
|
Benchmarks again: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/151/ |
Sorry, something went wrong.
There was a problem hiding this comment.
So - this does seem more useful than I thought. (With a request, like a session, you might need to store it in e.g. Redis.)
I'm going to guess the perf drop is due to some polymorphism? Maybe we should run turbolizer against it. I'm not yet going to unblock this yet but I wonder if the perf hit is really that much overall.
We should stress HTTP and see if cancel ticks go up significantly, I suppose.
Sorry, something went wrong.
|
|
||
| assert.strictEqual(Number.isNaN(+timeout1), false); | ||
| assert.strictEqual(Number.isNaN(+timeout2), false); | ||
|
|
There was a problem hiding this comment.
Can you check that +timeout1 === timeout1[Symbol.toPrimitive]()?
Sorry, something went wrong.
|
@bmeck I have a suggestion to make, if I may: We can still get the functionality here while delaying perf concerns in the following way:
This has the following advantages:
If you're still interested, I would gladly review that kind of update. If not, mind if I take the existing commits and adjust? |
Sorry, something went wrong.
|
Im on vacation but would object to those suggested differences.
…On Thu, Apr 26, 2018, 12:43 AM Jeremiah Senkpiel ***@***.***> wrote:
@bmeck <https://github.com/bmeck> I have a suggestion to make, if I may:
We can still get the functionality here while delaying perf concerns in
the following way:
- Keep the toPrimitive
- Remove the id detection / polymorphism from existing timers methods
- Add a getTimerById (or similar) to get a timer object by the
primitive id
This has the following advantages:
- Allows the funcionality
- Avoids polymorphism & existing perf concerns
- Allows timers to be refreshed from id (see #20261 (comment)
<#20261 (comment)>)
If you're still interested, I would gladly review that kind of update. If
not, mind if I take the existing commits and adjust?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#19683 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAOUo9g2Dh_7r20OAuAmEcJDcQNZO8aUks5tsJmtgaJpZM4TA7q->
.
|
Sorry, something went wrong.
|
@bmeck if you still want to pursue this, instead of doing the more expensive in check — you could just set a flag when a timer is converted to a number. In addition, the check within clearTimeout could be reversed. First check whether timer is true & has _onTimeout, then do the typeof check (get the timer, etc.) and call clearTimeout again with the result. |
Sorry, something went wrong.
|
I'd love to see how @apapirovski's suggestions work out. |
Sorry, something went wrong.
|
@bmeck Do you want to continue on this or can I take over basing on top of your commit (with credit preserved)? I like the idea but I think I've got some solid ideas on how to make it faster, as expressed above. |
Sorry, something went wrong.
|
@apapirovski please take it over, your work is quite exciting :) |
Sorry, something went wrong.
|
@bmeck thanks! I'll pull in your commit and build on top of it. 👍 I'll preserve the credit when/if I open a PR, depending on how the perf works out. |
Sorry, something went wrong.
|
I'll close this out since there's a more up-to-date / rebased version. Hopefully we can sort out the remaining issues to land it. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
For web compatibility this allows timers to be stored as the key
of an Object property and be passed back to corresponding method to
clear the timer.
Note that this is using the async_id_symbol to get a numeric ID to correspond with timers.
Checklist