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: do not expose .unref()._handle._list #8422

Closed

Conversation

Fishrock123
Copy link
Contributor

@Fishrock123 Fishrock123 commented Sep 6, 2016

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

timers

Description of change

The list is defunct at this point.
I believe this to be in effect a minor defect/oversight from
3eecdf9

Tangentially effects/related to #8372

Edit: cc @indutny?

@Fishrock123 Fishrock123 added the timers Issues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout. label Sep 6, 2016
lib/timers.js Outdated
@@ -481,6 +481,7 @@ Timeout.prototype.unref = function() {
}

var handle = reuse(this);
delete handle._list;

Choose a reason for hiding this comment

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

I thought V8 don't like deleting props prom objects, but it might be ok if it is not perf-sensitive...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Under #8372 this code path is far less likely to be hit in the first place.

I doubt the overhead from a later-than-this-tick unref() is much of a worry.

Choose a reason for hiding this comment

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

Why not removing the reference to the TimersList instance in reuse's implementation instead?

Also, #8372 hasn't landed yet, and it's not clear whether it will land. As a result I would think that if deleting the ._list property is more costly than setting it to null (or doing anything else that we know might perform better), we should not do that and instead do what we know performs better.

Copy link
Contributor Author

@Fishrock123 Fishrock123 Sep 6, 2016

Choose a reason for hiding this comment

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

Why not removing the reference to the TimersList instance in reuse's implementation instead?

Messes with some tests that check things after unenroll(), which also uses reuse().

Setting it to undefined would be faster but I figured it could be confusing that sometimes there would be a _list property.

If that is acceptable we can switch to it though.

Copy link

@misterdjules misterdjules Sep 7, 2016

Choose a reason for hiding this comment

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

Why not removing the reference to the TimersList instance in reuse's implementation instead?

Messes with some tests that check things after unenroll(), which also uses reuse().

Making that change (clearing the handle's reference to the TimersList instance) makes only one test fail on master: test/parallel/test-timers-same-timeout-wrong-list-deleted.js. I think that test could be updated to not rely on that reference being present for unenrolled timers.

Is this what you had in mind by "Messes with some tests"?

Choose a reason for hiding this comment

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

@Fishrock123

delete is known to be a heavy operation.

I thought we were also considering setting the property to null or undefined, isn't it still the case?

You mentioned earlier:

Setting it to undefined would be faster but I figured it could be confusing that sometimes there would be a _list property.

If that is acceptable we can switch to it though.

Having a _list property set to null or undefined seems like it would be acceptable.

Copy link
Member

Choose a reason for hiding this comment

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

Should we just use Symbols for _list?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could, I thought those were exposable somehow too?

I still think we should unreference it in some way though so the list can be GC'd.

Copy link
Member

Choose a reason for hiding this comment

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

Using a Symbol and setting the value to undefined would accomplish both goals without incurring the potential perf hit of the delete, yes? Symbols are exposable but not without extra work.

Copy link
Contributor

Choose a reason for hiding this comment

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

or, why don't we set it to null. we already do that for some other properties like _handle.

@Fishrock123
Copy link
Contributor Author

cc also @misterdjules maybe?

@misterdjules
Copy link

The idea seems reasonable, I added a couple comments regarding the implementation.

@misterdjules
Copy link

It seems that removing the ._list property would be a breaking change. Setting it to null or undefined could be considered as a breaking change too. As a result it seems this change should be labelled semver-major.

@Fishrock123
Copy link
Contributor Author

It seems that removing the ._list property would be a breaking change.

Theoretically but I'm willing to bet no one even knew it existed.

@misterdjules
Copy link

@Fishrock123

It seems that removing the ._list property would be a breaking change.

Theoretically but I'm willing to bet no one even knew it existed.

Can we use https://github.com/ChALkeR/Gzemnid to look into that? I would like to err on the side of caution regardless of the results, unless the benefits of the change far outweigh the risks, however unlikely.

@Fishrock123
Copy link
Contributor Author

cc @ChALkeR?

I dunno how this would be detected, but I guess you could look for ._list?

@ChALkeR
Copy link
Member

ChALkeR commented Sep 15, 2016

There is a lot of stuff on \._list[^a-zA-Z0-9_], but the lines I seen don't look timers related.
Also a lot of stuff on \._handle[^a-zA-Z0-9_].

Nothing on handle\._list, but that doesn't guarantee anything.
I will take a closer look soon.

@rvagg rvagg force-pushed the master branch 2 times, most recently from c133999 to 83c7a88 Compare October 18, 2016 17:02
@Fishrock123 Fishrock123 added the semver-major PRs that contain breaking changes and should be released in the next major version. label Jan 5, 2017
@Fishrock123
Copy link
Contributor Author

@nodejs/ctc Anyone object to me merging this one as a major?

The _handle._list double-private property is only exposed under a specific condition and is non-functional when it is exposed.

@targos
Copy link
Member

targos commented Jan 6, 2017

+1

indutny
indutny previously requested changes Jan 6, 2017
@trevnorris
Copy link
Contributor

@Fishrock123 If it's non-functional when it's exposed then I'd consider this a bug fix. Or at most a minor. Calling this a major seems like far overkill. We're removing a property that's broken right?

@Fishrock123
Copy link
Contributor Author

@trevnorris The property exists, but it doesn't actually have any relevant functionality since it is circularly attached to a handle which is repurposed for an individual timeout.

@Fishrock123
Copy link
Contributor Author

@indutny What's the point? This is the only spot where it is exposed to a user.

@jasnell
Copy link
Member

jasnell commented Mar 1, 2017

ping @Fishrock123 ... still making progress on this?

@jasnell
Copy link
Member

jasnell commented Mar 22, 2017

Ping @Fishrock123 ...

@jasnell jasnell added the stalled Issues and PRs that are stalled. label Mar 22, 2017
@Fishrock123
Copy link
Contributor Author

@indutny Is there a large benefit here to using Symbols rather than just deleting it?

I mean with any property symbol or not I guess we could just set it to undefined but it'd be weird that it is there at all imo. Could work though...

@Fishrock123
Copy link
Contributor Author

Fishrock123 commented Mar 24, 2017

Updated to null out the property. New CI: https://ci.nodejs.org/job/node-test-pull-request/7020/

@indutny, @misterdjules lgty?

@nodejs/ctc please take a quick look if you could since it is semver-major.

@Fishrock123
Copy link
Contributor Author

Oops, actually new CI: https://ci.nodejs.org/job/node-test-pull-request/7021/

Copy link

@misterdjules misterdjules left a comment

Choose a reason for hiding this comment

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

The following test program:

setTimeout(function foo() {}, 1000);
setTimeout(function foo() {}, 1000).unref();

breaks with this change:

$ cat /var/tmp/test-settimeout-unref.js 
setTimeout(function foo() {}, 1000);
setTimeout(function foo() {}, 1000).unref();
$ ./node /var/tmp/test-settimeout-unref.js 
timers.js:541
    handle._list = null;
                 ^

TypeError: Cannot set property '_list' of null
    at Timeout.unref (timers.js:541:18)
    at Object.<anonymous> (/private/var/tmp/test-settimeout-unref.js:2:37)
    at Module._compile (module.js:607:30)
    at Object.Module._extensions..js (module.js:618:10)
    at Module.load (module.js:516:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.runMain (module.js:643:10)
    at run (bootstrap_node.js:444:7)
    at startup (bootstrap_node.js:151:9)
$

and runs successfully without this change.

lib/timers.js Outdated
@@ -538,6 +538,7 @@ Timeout.prototype.unref = function() {
}

var handle = reuse(this);
handle._list = null;

Choose a reason for hiding this comment

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

What happens when handle is null?

@Fishrock123
Copy link
Contributor Author

@@ -0,0 +1,16 @@
'use strict';

Choose a reason for hiding this comment

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

Does this need a license block now that #10155 landed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

... No? It did not have previous attribution? (It's new?)

Choose a reason for hiding this comment

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

OK, it's been a while I haven't added a file to the repository, and it seems files added in the recent past did not include a license block, so it sounds good to me!

// Check that everything works even if the handle was not re-used.
setTimeout(() => {}, 1);
const timer2 = setTimeout(() => {}, 1).unref();
// Note: It is unlikely that this assertion will be hit in a failure.

Choose a reason for hiding this comment

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

That comment seems to be specific to a previous version of this PR where it would throw in that case. I don't think it's relevant in the final version.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really, the comment states if that were to fail, i.e. the conditional was removed, node will explode internally rather than triggering this assertion.

Choose a reason for hiding this comment

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

Why would "a failure" be specifically that "the conditional was removed"? This is anticipating the future, and not reflecting the current state of the code base. Without the context of what this PR looked like in an intermediate version, this comment doesn't make any sense.

I still think it's not relevant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can't think of how this will change without removing handle re-use... Are you saying that a comment that either: might be useful or not matter at all would be better off not being there at all? Isn't that every comment ever?

That bit of code does primarily test that conditional though, that isn't a problem IMO. We have added plenty of test code for code coverage that would be similar.

Copy link

@misterdjules misterdjules Apr 13, 2017

Choose a reason for hiding this comment

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

The test code itself is great, and the comment above:

// Check that everything works even if the handle was not re-used.

is both necessary and sufficient to explain why this test code is present.

On the other hand, I find the comment:

// Note: It is unlikely that this assertion will be hit in a failure.
// Instead, timers.js will likely throw a TypeError internally.

confusing and detrimental to the understanding of that test because it does not reflect the current state of the implementation. Instead it describes what could happen if the code was changed in a specific way, that is if a conditional was removed.

I don't think we want to start documenting every possible way this test could fail depending on an infinite list of possible changes, or by definition we will end up with an infinite list of comments.

Copy link

@misterdjules misterdjules left a comment

Choose a reason for hiding this comment

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

A few more comments about the form, otherwise I'm OK wit the nature of the changes.

@Fishrock123
Copy link
Contributor Author

@misterdjules I believe I have addressed your comments.

@indutny last chance to look, I assume you are not exactly interested so I'll be dismissing your review as it was long since addressed.

@Fishrock123
Copy link
Contributor Author

@misterdjules updated, lgty?

@Fishrock123
Copy link
Contributor Author

Here's a CITGM run although I'd be far beyond surprised if we covered a module interacting with this in any way. https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/719/

@misterdjules misterdjules removed the stalled Issues and PRs that are stalled. label Apr 20, 2017
@BridgeAR
Copy link
Member

@indutny you never responded back and this is blocked because of that. It could land otherwise so it would be nice if you could have a look.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM..

can we land this before 9?

@indutny can you review again?

@BridgeAR BridgeAR dismissed indutny’s stale review September 20, 2017 00:57

Dismissing the review due to no response. Please take another look.

@BridgeAR
Copy link
Member

I dismissed the review of @indutny. @nodejs/tsc PTAL because of that. This should be ready to land otherwise.

@mcollina
Copy link
Member

let’s land this.

@jasnell
Copy link
Member

jasnell commented Sep 20, 2017

@BridgeAR
Copy link
Member

BridgeAR commented Sep 20, 2017

Landed in 11f7dcf

@BridgeAR BridgeAR closed this Sep 20, 2017
BridgeAR pushed a commit that referenced this pull request Sep 20, 2017
The list is defunct at this point.
I believe this to be in effect a minor defect from
3eecdf9

PR-URL: #8422
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Qard pushed a commit to Qard/ayo that referenced this pull request Sep 21, 2017
The list is defunct at this point.
I believe this to be in effect a minor defect from
3eecdf9

PR-URL: nodejs/node#8422
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Qard pushed a commit to Qard/ayo that referenced this pull request Sep 21, 2017
The list is defunct at this point.
I believe this to be in effect a minor defect from
3eecdf9

PR-URL: nodejs/node#8422
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-major PRs that contain breaking changes and should be released in the next major version. 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.