Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

doc: WIP update timers/nextTick documentation #5950

Closed
wants to merge 1 commit into from
Closed

doc: WIP update timers/nextTick documentation #5950

wants to merge 1 commit into from

Conversation

trevnorris
Copy link

Still in the works, but put in your 2 cents along the way.

@@ -456,14 +456,16 @@ This will generate:

* `callback` {Function}

Once the current event loop turn runs to completion, call the callback
function.
Add a callback to the `nextTickQueue`.
Copy link
Member

Choose a reason for hiding this comment

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

Something like "Schedules a callback to run as soon as possible but no sooner."? (Half tongue in cheek.)

@isaacs
Copy link

isaacs commented Aug 5, 2013

Apart from teh nit about stability level, lgtm.

This is important in developing APIs where you want to give the user the
chance to assign event handlers after an object has been constructed,
but before any I/O has occurred.
`process.nextTick` is specifically important when developing an event based API

Choose a reason for hiding this comment

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

I would like to deemphasize this in favor of setImmediate it would be nice to call it out here that because of the starvation warning that it's strongly advised that users now use setImmediate

Copy link
Author

Choose a reason for hiding this comment

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

True that.

Choose a reason for hiding this comment

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

So, I used to know why to call .nextTick(), but then @bnoordhuis made
.setImmediate() much faster, and I think @trevnorris removed the
problems/limits on recursive call of .nextTick(), and I no longer
understand why you would use one vs the other.

Can someone explain why node shouldn't just do process.nextTick = process.setImmediate?

And make some clear statement in the docs about under what circumstances
one should be used, vs the other?

Most reasonable use for deferred callbacks is when returning an EE, and
wanting to give caller a chance to listen on events. Next most reasonable
is when an API is usually async, and you want to make sure it is always
async.

In those cases, is the prefered API now .setImmediate, or is it still
.nextTick?

Copy link

Choose a reason for hiding this comment

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

AFAIK setImmediate(f) is conceptually === setTimeout(f, 0)

The setImmediate queue is dispatched only once per event loop turn, like so:

1.- Grab the setImmediateQueue, call it currentSetImmediateQueue,
2.- Put a new, empty, setImmediateQueue in its place
3.- Call everything that's in the currentSetImmediateQueue

But the netTick queue is serviced more than once, as often as needed per event loop turn, like so:

while (nextTickQueue.length) nextTickQueue.shift()()

So:

1.- When you add an item to the nextTickQueue from a function in the nextTickQueue, it will simply make that while() loop above loop once more, but when you add an item to the setImmediateQueue, the newly added item won't run until the next turn of the event loop (and many other callbacks may have been called in-between, by then)
2.- Recursively adding to the nextTickQueue blocks the event loop.
3.- Recursively adding to the setImmediateQueue does not block the event loop.
4.- If you want to be totally sure that no other callback (*) runs before f, use .nextTick(f).

(*) Any other cb that was already in the nextTickQueue will still run before f, though.

Choose a reason for hiding this comment

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

what @xk says is right, I would like to add the emphasis that when you do queue with setImmediate you are sure to always get called on the next turn of the event loop, where as nextTick's queue can be cleared multiple times as people transition through MakeCallback.

The fact that this logic makes it nice to make sure your cb will fire "before" others, is a side effect and shouldn't be relied upon outside of core anyway, hence my insistence to deemphasize the use of nextTick in general.

(Also nextTick doesn't and likely won't take arguments to be passed to the function)

Choose a reason for hiding this comment

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

So is it safe to say we can just use setImmediate unless we want to make sure cb is called at the beginning of next tick(except reaching maxTickDepth)? And cb of setImmediate will be significantly delayed if long blocking code gets called by i/o events before immediates?

Choose a reason for hiding this comment

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

It's safe to say, you want to use setImmediate unless there is clear evidence that you need this callback to run before any other IO notification. Out side of core I am skeptical that that distinction means anything to anyone as you have no real visibility into what actually is happening, so it's just always preferred to use setImmediate

@trevnorris
Copy link
Author

process.nextTick() will run something asynchronously, but before the event loop has a chance to continue. setImmediate runs at the end of each event loop.

@trevnorris
Copy link
Author

I'll resurrect this soon as I get through the stuff that's on fire.

@jasnell
Copy link
Member

jasnell commented Jun 3, 2015

@trevnorris ... is this still on your todo list ;-)

@trevnorris
Copy link
Author

@jasnell hah. nope.

@trevnorris
Copy link
Author

Closing. If someone wants to take this on and polish it up feel free.

@trevnorris trevnorris closed this Jun 23, 2015
gibfahn pushed a commit to ibmruntimes/node that referenced this pull request Apr 26, 2016
The following significant (semver-major) changes have been made since the
previous Node v5.0.0 release.

* Buffer
  * New Buffer constructors have been added
    [nodejs#4682](nodejs/node#4682)
  * Previously deprecated Buffer APIs are removed
    [nodejs#5048](nodejs/node#5048),
    [nodejs#4594](nodejs/node#4594)
  * Improved error handling [nodejs#4514](nodejs/node#4514)
* Cluster
  * Worker emitted as first argument in 'message' event
    [nodejs#5361](nodejs/node#5361).
* Crypto
  * Improved error handling [nodejs#3100](nodejs/node#3100),
    [nodejs#5611](nodejs/node#5611)
  * Simplified Certificate class bindings
    [nodejs#5382](nodejs/node#5382)
  * Improved control over FIPS mode
    [nodejs#5181](nodejs/node#5181)
  * pbkdf2 digest overloading is deprecated
    [nodejs#4047](nodejs/node#4047)
* Dependencies
  * Reintroduce shared c-ares build support
    [nodejs#5775](nodejs/node#5775).
  * V8 updated to 5.0.71.31 [nodejs#6111](nodejs/node#6111).
* DNS
  * Add resolvePtr API to query plain DNS PTR records
    [nodejs#4921](nodejs/node#4921).
* Domains
  * Clear stack when no error handler
  [nodejs#4659](nodejs/node#4659).
* File System
  * The `fs.realpath()` and `fs.realpathSync()` methods have been updated
    to use a more efficient libuv implementation. This change includes the
    removal of the `cache` argument and the method can throw new errors
    [nodejs#3594](nodejs/node#3594)
  * FS apis can now accept and return paths as Buffers
    [nodejs#5616](nodejs/node#5616).
  * Error handling and type checking improvements
    [nodejs#5616](nodejs/node#5616),
    [nodejs#5590](nodejs/node#5590),
    [nodejs#4518](nodejs/node#4518),
    [nodejs#3917](nodejs/node#3917).
  * fs.read's string interface is deprecated
    [nodejs#4525](nodejs/node#4525)
* HTTP
  * 'clientError' can now be used to return custom errors from an
    HTTP server [nodejs#4557](nodejs/node#4557).
* Modules
  * Current directory is now prioritized for local lookups
    [nodejs#5689](nodejs/node#5689)
  * Symbolic links are preserved when requiring modules
    [nodejs#5950](nodejs/node#5950)
* Net
  * DNS hints no longer implicitly set
    [nodejs#6021](nodejs/node#6021).
  * Improved error handling and type checking
    [nodejs#5981](nodejs/node#5981),
    [nodejs#5733](nodejs/node#5733),
    [nodejs#2904](nodejs/node#2904)
* Path
  * Improved type checking [nodejs#5348](nodejs/node#5348).
* Process
  * Introduce process warnings API
    [nodejs#4782](nodejs/node#4782).
  * Throw exception when non-function passed to nextTick
    [nodejs#3860](nodejs/node#3860).
* Readline
  * Emit key info unconditionally
    [nodejs#6024](nodejs/node#6024)
* REPL
  * Assignment to `_` will emit a warning.
    [nodejs#5535](nodejs/node#5535)
* Timers
  * Fail early when callback is not a function
    [nodejs#4362](nodejs/node#4362)
* TLS
  * Rename 'clientError' to 'tlsClientError'
    [nodejs#4557](nodejs/node#4557)
  * SHA1 used for sessionIdContext
    [nodejs#3866](nodejs/node#3866)
* TTY
  * Previously deprecated setRawMode wrapper is removed
    [nodejs#2528](nodejs/node#2528).
* Util
  * Changes to Error object formatting
    [nodejs#4582](nodejs/node#4582).
* Windows
  * Windows XP and Vista are no longer supported
    [nodejs#5167](nodejs/node#5167),
    [nodejs#5167](nodejs/node#5167).
gibfahn pushed a commit to ibmruntimes/node that referenced this pull request Apr 27, 2016
The following significant (semver-major) changes have been made since the
previous Node v5.0.0 release.

* Buffer
  * New Buffer constructors have been added
    [nodejs#4682](nodejs/node#4682)
  * Previously deprecated Buffer APIs are removed
    [nodejs#5048](nodejs/node#5048),
    [nodejs#4594](nodejs/node#4594)
  * Improved error handling [nodejs#4514](nodejs/node#4514)
* Cluster
  * Worker emitted as first argument in 'message' event
    [nodejs#5361](nodejs/node#5361).
* Crypto
  * Improved error handling [nodejs#3100](nodejs/node#3100),
    [nodejs#5611](nodejs/node#5611)
  * Simplified Certificate class bindings
    [nodejs#5382](nodejs/node#5382)
  * Improved control over FIPS mode
    [nodejs#5181](nodejs/node#5181)
  * pbkdf2 digest overloading is deprecated
    [nodejs#4047](nodejs/node#4047)
* Dependencies
  * Reintroduce shared c-ares build support
    [nodejs#5775](nodejs/node#5775).
  * V8 updated to 5.0.71.31 [nodejs#6111](nodejs/node#6111).
* DNS
  * Add resolvePtr API to query plain DNS PTR records
    [nodejs#4921](nodejs/node#4921).
* Domains
  * Clear stack when no error handler
  [nodejs#4659](nodejs/node#4659).
* File System
  * The `fs.realpath()` and `fs.realpathSync()` methods have been updated
    to use a more efficient libuv implementation. This change includes the
    removal of the `cache` argument and the method can throw new errors
    [nodejs#3594](nodejs/node#3594)
  * FS apis can now accept and return paths as Buffers
    [nodejs#5616](nodejs/node#5616).
  * Error handling and type checking improvements
    [nodejs#5616](nodejs/node#5616),
    [nodejs#5590](nodejs/node#5590),
    [nodejs#4518](nodejs/node#4518),
    [nodejs#3917](nodejs/node#3917).
  * fs.read's string interface is deprecated
    [nodejs#4525](nodejs/node#4525)
* HTTP
  * 'clientError' can now be used to return custom errors from an
    HTTP server [nodejs#4557](nodejs/node#4557).
* Modules
  * Current directory is now prioritized for local lookups
    [nodejs#5689](nodejs/node#5689)
  * Symbolic links are preserved when requiring modules
    [nodejs#5950](nodejs/node#5950)
* Net
  * DNS hints no longer implicitly set
    [nodejs#6021](nodejs/node#6021).
  * Improved error handling and type checking
    [nodejs#5981](nodejs/node#5981),
    [nodejs#5733](nodejs/node#5733),
    [nodejs#2904](nodejs/node#2904)
* OS X
  * MACOSX_DEPLOYMENT_TARGET has been bumped up to 10.7
    [nodejs#6402](nodejs/node#6402).
* Path
  * Improved type checking [nodejs#5348](nodejs/node#5348).
* Process
  * Introduce process warnings API
    [nodejs#4782](nodejs/node#4782).
  * Throw exception when non-function passed to nextTick
    [nodejs#3860](nodejs/node#3860).
* Readline
  * Emit key info unconditionally
    [nodejs#6024](nodejs/node#6024)
* REPL
  * Assignment to `_` will emit a warning.
    [nodejs#5535](nodejs/node#5535)
* Timers
  * Fail early when callback is not a function
    [nodejs#4362](nodejs/node#4362)
* TLS
  * Rename 'clientError' to 'tlsClientError'
    [nodejs#4557](nodejs/node#4557)
  * SHA1 used for sessionIdContext
    [nodejs#3866](nodejs/node#3866)
* TTY
  * Previously deprecated setRawMode wrapper is removed
    [nodejs#2528](nodejs/node#2528).
* Util
  * Changes to Error object formatting
    [nodejs#4582](nodejs/node#4582).
* Windows
  * Windows XP and Vista are no longer supported
    [nodejs#5167](nodejs/node#5167),
    [nodejs#5167](nodejs/node#5167).
gibfahn pushed a commit to ibmruntimes/node that referenced this pull request May 6, 2016
The following significant (semver-major) changes have been made since the
previous Node v5.0.0 release.

* Buffer
  * New Buffer constructors have been added
    [nodejs#4682](nodejs/node#4682)
  * Previously deprecated Buffer APIs are removed
    [nodejs#5048](nodejs/node#5048),
    [nodejs#4594](nodejs/node#4594)
  * Improved error handling [nodejs#4514](nodejs/node#4514)
* Cluster
  * Worker emitted as first argument in 'message' event
    [nodejs#5361](nodejs/node#5361).
* Crypto
  * Improved error handling [nodejs#3100](nodejs/node#3100),
    [nodejs#5611](nodejs/node#5611)
  * Simplified Certificate class bindings
    [nodejs#5382](nodejs/node#5382)
  * Improved control over FIPS mode
    [nodejs#5181](nodejs/node#5181)
  * pbkdf2 digest overloading is deprecated
    [nodejs#4047](nodejs/node#4047)
* Dependencies
  * Reintroduce shared c-ares build support
    [nodejs#5775](nodejs/node#5775).
  * V8 updated to 5.0.71.31 [nodejs#6111](nodejs/node#6111).
* DNS
  * Add resolvePtr API to query plain DNS PTR records
    [nodejs#4921](nodejs/node#4921).
* Domains
  * Clear stack when no error handler
  [nodejs#4659](nodejs/node#4659).
* File System
  * The `fs.realpath()` and `fs.realpathSync()` methods have been updated
    to use a more efficient libuv implementation. This change includes the
    removal of the `cache` argument and the method can throw new errors
    [nodejs#3594](nodejs/node#3594)
  * FS apis can now accept and return paths as Buffers
    [nodejs#5616](nodejs/node#5616).
  * Error handling and type checking improvements
    [nodejs#5616](nodejs/node#5616),
    [nodejs#5590](nodejs/node#5590),
    [nodejs#4518](nodejs/node#4518),
    [nodejs#3917](nodejs/node#3917).
  * fs.read's string interface is deprecated
    [nodejs#4525](nodejs/node#4525)
* HTTP
  * 'clientError' can now be used to return custom errors from an
    HTTP server [nodejs#4557](nodejs/node#4557).
* Modules
  * Current directory is now prioritized for local lookups
    [nodejs#5689](nodejs/node#5689)
  * Symbolic links are preserved when requiring modules
    [nodejs#5950](nodejs/node#5950)
* Net
  * DNS hints no longer implicitly set
    [nodejs#6021](nodejs/node#6021).
  * Improved error handling and type checking
    [nodejs#5981](nodejs/node#5981),
    [nodejs#5733](nodejs/node#5733),
    [nodejs#2904](nodejs/node#2904)
* OS X
  * MACOSX_DEPLOYMENT_TARGET has been bumped up to 10.7
    [nodejs#6402](nodejs/node#6402).
* Path
  * Improved type checking [nodejs#5348](nodejs/node#5348).
* Process
  * Introduce process warnings API
    [nodejs#4782](nodejs/node#4782).
  * Throw exception when non-function passed to nextTick
    [nodejs#3860](nodejs/node#3860).
* Readline
  * Emit key info unconditionally
    [nodejs#6024](nodejs/node#6024)
* REPL
  * Assignment to `_` will emit a warning.
    [nodejs#5535](nodejs/node#5535)
* Timers
  * Fail early when callback is not a function
    [nodejs#4362](nodejs/node#4362)
* TLS
  * Rename 'clientError' to 'tlsClientError'
    [nodejs#4557](nodejs/node#4557)
  * SHA1 used for sessionIdContext
    [nodejs#3866](nodejs/node#3866)
* TTY
  * Previously deprecated setRawMode wrapper is removed
    [nodejs#2528](nodejs/node#2528).
* Util
  * Changes to Error object formatting
    [nodejs#4582](nodejs/node#4582).
* Windows
  * Windows XP and Vista are no longer supported
    [nodejs#5167](nodejs/node#5167),
    [nodejs#5167](nodejs/node#5167).
richardlau pushed a commit to ibmruntimes/node that referenced this pull request May 17, 2016
Add the `--preserve-symlinks` flag. This makes the changes added
in nodejs#5950 conditional. By default the old behavior is used. With
the flag set, symlinks are preserved, switching to the new
behavior. This should be considered to be a temporary solution
until we figure out how to solve the symlinked peer dependency
problem in a more general way that does not break everything
else.

Additional test cases are included.

PR-URL: nodejs/node#6537
Reviewed-By: Ben Noordhuis <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants