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

doc: add active, enroll and unenroll #11736

Closed
wants to merge 3 commits into from
Closed

Conversation

jsumners
Copy link
Contributor

@jsumners jsumners commented Mar 7, 2017

This PR adds documentation for the public timers methods
active, enroll and unenroll.

Checklist
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

doc

@nodejs-github-bot nodejs-github-bot added doc Issues and PRs related to the documentations. timers Issues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout. labels Mar 7, 2017
Example:

```js
var timers = require('timers')
Copy link
Contributor

Choose a reason for hiding this comment

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

This and other lines are missing semicolons.

```js
var timers = require('timers')
var atimer = {
_onTimeout: function () {
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nit: should be function() {

@mscdex
Copy link
Contributor

mscdex commented Mar 8, 2017

I'm not sure if these methods are actually intended to be public or not, even though they are not underscore-prefixed?

/cc @Fishrock123

This commit adds documentation for the public `timers` methods
`active`, `enroll` and `unenroll`.
@jasnell
Copy link
Member

jasnell commented Mar 8, 2017

At this point (a) they're public and (b) being used, we may as well document them.

@Fishrock123
Copy link
Contributor

Fishrock123 commented Mar 8, 2017

I very much don't think we should document them as for public use.

  1. The memory use is negligible and is far far less difference than "slightly".
  2. You need to pre-setup objects to prevent them from de-opting (hidden class changes).
  3. The API is very confusing.

It may be worthwhile to mention more specifics of the timers implementation that relate to these, such as that unenroll() is called at pretty much every cancel path, among other minor details.

If we want to mention actually useful stuff, then we should probably mention just active(), which can be used to refresh a timeout timer without creating a new object.

@jsumners
Copy link
Contributor Author

jsumners commented Mar 8, 2017

I couldn't think of much for an introduction. So I copied the point made about enroll that is in the source code and added my observation about more control. If there are suggestions for a better introduction, I am more than willing to listen.

As for the API being confusing, it was more confusing when I learned about it via its usage in https://github.com/davidmarkclements/fast-date/blob/master/fallback.js and there wasn't any documentation on it.

@Fishrock123
Copy link
Contributor

Fishrock123 commented Mar 8, 2017

As for the API being confusing, it was more confusing when I learned about it via its usage in https://github.com/davidmarkclements/fast-date/blob/master/fallback.js and there wasn't any documentation on it.

uuuugh ok. Let's document it but tell people to not use it / avoid it.

@jsumners
Copy link
Contributor Author

jsumners commented Mar 8, 2017

@Fishrock123 how would you revise the introduction?

@jasnell
Copy link
Member

jasnell commented Mar 8, 2017

Aside: I've been stewing over whether we need an official not-recommended-for-use-but-not-quite-deprecated status for various APIs or if calling them out individually as don't use it on a case by case basis is enough. The challenge is that people will flat out ignore it but having a clearly documented status gives us some leeway for making changes later if necessary.

@jsumners
Copy link
Contributor Author

jsumners commented Mar 8, 2017

@jasnell would the classification you're looking for be "volatile"?

@jasnell
Copy link
Member

jasnell commented Mar 8, 2017

No, because the APIs in question might not change frequently or at all. They may ... the defining characteristic would be that they simply are not recommended (for whatever reason)

@Qard
Copy link
Member

Qard commented Mar 8, 2017

In a way, I think it's similar to unsafe in Rust. You could enroll an object and forget to use it, leaking memory.

@joyeecheung
Copy link
Member

@jasnell Maybe make those APIs non-enumerable so they don't show up in auto-completion would be a start..

@jasnell
Copy link
Member

jasnell commented Mar 15, 2017

@nodejs/ctc @Fishrock123 ... would appreciate more input on this

@bnoordhuis
Copy link
Member

They were never intended for public use, just an implementation detail that leaked out due to lack of foresight.

If the argument for documenting them is to avoid confusion for people stumbling upon them, it should be a one-liner like "Implementation detail. Do not use."

@davidmarkclements
Copy link
Member

Personally I'd prefer a warning about cleaning up state than warning not to use - especially because I've now used it in a published module as a performance enhancement.

@jsumners
Copy link
Contributor Author

How about this intro:

It is possible to make any object a timer. The advantage of doing so is being able to
control when the timer is started, as opposed to the other timers which start immediately.

Warning: using this API means you must keep track of the timer state. If you create
a timer, but never unenroll it, then you will introduce a memory leak.

@jasnell
Copy link
Member

jasnell commented Mar 20, 2017

In general, please avoid the use of directed pronouns like you or your in documentation text. The warning could be reworded as:

*Note*: When using this API, it is important to track timer enrollment state. A memory leak
will occur if a timer is enrolled but never unenrolled.

@jasnell
Copy link
Member

jasnell commented Mar 20, 2017

I definitely agree with @bnoordhuis' sentiment that the added documentation should include a strong warning against using these methods. It should likely also be noted that the specific implementation details of these particular methods could change and that while the API is publicly accessible, ongoing support is not guaranteed. (That said, we would definitely have to take any changes to these through a proper deprecation cycle in practice)

@jsumners
Copy link
Contributor Author

@jasnell so do you have any other changes for the proposed introduction rewording?

Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

In general this definitely needs the warning text and a clear description of the state management requirements.

## Manual Timers

It is possible to make any object a timer. Reusing an existing object as a timer
slightly reduces memory consumption. Another advantage is that you control
Copy link
Member

Choose a reason for hiding this comment

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

Again, please avoid the use of you in the documentation text :-)


```js
var timers = require('timers');
var atimer = {
Copy link
Member

Choose a reason for hiding this comment

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

s/var/const

@@ -162,6 +162,50 @@ added: v0.0.1

Cancels a `Timeout` object created by [`setTimeout()`][].

## Manual Timers

It is possible to make any object a timer. Reusing an existing object as a timer
Copy link
Member

Choose a reason for hiding this comment

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

I would say something like, It is possible, but not recommended, to make any object into a timer.

@bnoordhuis
Copy link
Member

I'm still -1 on anything beyond a "do not use." The language proposed in #11736 (comment) is still an encouragement to use them.

It's easy enough to make a queue or linked list that hangs off a setTimeout() timer, you don't need enroll/unenroll for that.

@jasnell
Copy link
Member

jasnell commented Mar 20, 2017

@bnoordhuis ... if the APIs really should not be used then we should move the implementation to lib/internal and do a runtime deprecation of the public methods.

@jsumners
Copy link
Contributor Author

I agree. I understand that it may have been a mistake, but they are written with the convention implying they are a public API. My opinion is that any such API should be documented since people will find it, and they will use it under the assumption that it is public.

@bnoordhuis
Copy link
Member

Then a note in the documentation explaining they shouldn't be used should suffice. I'm not out to break existing code but new code should be steered away from using them.

Example:

```js
var timers = require('timers');
Copy link
Contributor

Choose a reason for hiding this comment

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

Please encourage Strict mode.

_onTimeout: function() {
console.log('timeout');
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Our coding standard expects a semi-colon at the end.

@mhdawson
Copy link
Member

mhdawson commented Apr 5, 2017

I agree with @bnoordhuis, given that we don't want people to use them, lets just say that and then start the deprecation process.

@vsemozhetbyt
Copy link
Contributor

circumstances this can be advantageous. However, in general practice, using
this API is strongly discouraged. This is due to the fact that when using this API
it is important to track timer enrollment state. A memory leak will occur if a
timer is enrolled but never unenrolled.
Copy link
Member

Choose a reason for hiding this comment

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

This paragraph can be simplified a bit...

It is possible (but not recommended) to make any object a timer. In general
practice, however, using this API is **strongly discouraged** due to the potential
for memory leaks should such timers fail to be properly unenrolled.


timers.enroll(atimer, 1000); // make the `atimer` object a timer
timers.active(atimer); // start the timer
```
Copy link
Member

Choose a reason for hiding this comment

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

This should include a clear example showing the timer being unenroll()'d per the warning above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does show it. Line 183, in the callback from the timer completion.

@BridgeAR
Copy link
Member

There was no progress here since a while and I fear this might not get merged as there were quite a few concerns about publishing this at all (and I share these concerns).
I also do not think that people who actually use non documented code will check if the documentation says "do not use this" or that they would care about it.
Therefore if there is no one strongly for including this I would like to go ahead and close this.

@jasnell
Copy link
Member

jasnell commented Aug 26, 2017

Closing this is ok. I do think something should be done here but this pr apparently isn't it.

@benjamingr benjamingr closed this Sep 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. 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.