Skip to content
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

timers: Implement conversion of timer argument #14817

Closed
wants to merge 1 commit into from

Conversation

starkwang
Copy link
Contributor

@starkwang starkwang commented Aug 14, 2017

"timer" argument should be converted to primitive, which makes the node API consistent with the browsers behavior.

Fix: #7792

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

timers

"timer" argument should be converted to primitive, which makes
the node API consistent with the browsers behavior.

Fix: nodejs#7792
@nodejs-github-bot nodejs-github-bot added the timers Issues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout. label Aug 14, 2017
@refack
Copy link
Contributor

refack commented Aug 14, 2017

Copy link
Member

@TimothyGu TimothyGu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is quite an interesting case, since browsers' timer methods return a number instead of an object, like we do. As such the clearing methods also need to coerce the argument to a number. However, while it seems more consistent to add coercion to our clearing methods, it breaks the language pact that @@toPrimitive, valueOf and toString should always return a primitive. It's unfortunate that we are using an object here rather than a number, but because of that I'm strongly -1 against this change.

@@ -500,8 +500,30 @@ function rearm(timer) {
}
}

function extractTimer(timer) {
if (Timeout.prototype.isPrototypeOf(timer) || typeof timer !== 'object' ||
timer === null || timer === undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could merge the last two as timer == null. It's a lite idiom used quite often in "core" to mean "something nully".
Also BTW typeof undefined !== object`, so the second clause covers it.

@@ -500,8 +500,30 @@ function rearm(timer) {
}
}

function extractTimer(timer) {
if (Timeout.prototype.isPrototypeOf(timer) || typeof timer !== 'object' ||
timer === null || timer === undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a case that need considering:

node/lib/net.js

Lines 381 to 396 in 472a665

Socket.prototype.setTimeout = function(msecs, callback) {
if (msecs === 0) {
timers.unenroll(this);
if (callback) {
this.removeListener('timeout', callback);
}
} else {
timers.enroll(this, msecs);
timers._unrefActive(this);
if (callback) {
this.once('timeout', callback);
}
}
return this;
};

(this is something we want to refactor in the future Ref: #14209)

@refack
Copy link
Contributor

refack commented Aug 14, 2017

So this is quite an interesting case, since browsers' timer methods return a number instead of an object, like we do. As such the clearing methods also need to coerce the argument to a number. However, while it seems more consistent to add coercion to our clearing methods, it breaks the language pact that @@toPrimitive, valueOf and toString should always return a primitive. It's unfortunate that we are using an object here rather than a number, but because of that I'm strongly -1 against this change.

What will be the ramification of changing node's setTimeout and setInterval to return a primitive? IMHO the docs are vague enough about the type returned that we could consider it - https://nodejs.org/dist/latest/docs/api/timers.html#timers_timers

@mscdex
Copy link
Contributor

mscdex commented Aug 14, 2017

I'm -1 as well. This will introduce unnecessary overhead for no real benefit.

Copy link
Contributor

@Fishrock123 Fishrock123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout instance APIs ref() and unref() make this impractical if not impossible.

I don't think this is worth the breakage and I'd consider it dead in the water as that ship sailed half a decade ago. Sorry. :/

@starkwang starkwang closed this Aug 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
timers Issues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inconsistent clearTimeout implementation (timer argument is not converted to primitive)
6 participants