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

tty: set the handle to blocking mode #6816

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,17 @@ Path to the file used to store the persistent REPL history. The default path is
to an empty string (`""` or `" "`) disables persistent REPL history.


### `NODE_TTY_UNSAFE_ASYNC=1`
<!-- YAML
added: REPLACEME
-->

When set to `1`, writes to `stdout` and `stderr` will be non-blocking and
asynchronous when outputting to a TTY on platforms which support async stdio.
Setting this will void any guarantee that stdio will not be interleaved or
dropped at program exit. **Use of this mode is not recommended.**


[Buffer]: buffer.html#buffer_buffer
[debugger]: debugger.html
[REPL]: repl.html
Expand Down
44 changes: 27 additions & 17 deletions doc/api/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -858,10 +858,9 @@ if (someConditionNotMet()) {
```

The reason this is problematic is because writes to `process.stdout` in Node.js
are usually *non-blocking* and may occur over multiple ticks of the Node.js
event loop.
Calling `process.exit()`, however, forces the process to exit *before* those
additional writes to `stdout` can be performed.
are sometimes *non-blocking* and may occur over multiple ticks of the Node.js
event loop. Calling `process.exit()`, however, forces the process to exit
*before* those additional writes to `stdout` can be performed.

Rather than calling `process.exit()` directly, the code *should* set the
`process.exitCode` and allow the process to exit naturally by avoiding
Expand Down Expand Up @@ -1429,15 +1428,20 @@ Android)
The `process.stderr` property returns a [Writable][] stream equivalent to or
associated with `stderr` (fd `2`).

`process.stderr` and `process.stdout` are unlike other streams in Node.js in
that they cannot be closed (calling [`end()`][] will throw an Error), they never
emit the [`'finish'`][] event, and writes can block when output is redirected to
a file (although disks are fast and operating systems normally employ write-back
caching so it should be a very rare occurrence indeed.)
Note: `process.stderr` and `process.stdout` differ from other Node.js streams
Copy link
Member

Choose a reason for hiding this comment

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

@jasnell I believe you are trying to standardize the format for Note: stuff in the docs, right? What did you settle on?

Copy link
Member

Choose a reason for hiding this comment

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

*Note*: would be the preference. Once I'm done going through all of the docs and standardizing the syntax I plan to work changes to the actual rendering of the notes in the docs based on the common format

in several ways:
1. They cannot be closed ([`end()`][] will throw).
2. They never emit the [`'finish'`][] event.
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need the additional square brackets for links I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh? These should use links defined at the bottom of the file...?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we have defined them at the bottom the empty square brackets are not necessary I think

3. Writes _can_ block when output is redirected to a file.
- Note that disks are fast and operating systems normally employ write-back
caching so this is very uncommon.
Copy link
Member

Choose a reason for hiding this comment

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

Nit: remove very

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 comfortable with that, that was the original wording.

Copy link
Member

@Trott Trott Jul 18, 2016

Choose a reason for hiding this comment

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

Yes, there should be a comma before so.

Also: very uncommon -> uncommon (EDIT: Not sure what you mean by "that was the original wording".)

Honestly, I would consider dispensing of the explanation entirely and just say: This is uncommon.

4. Writes on UNIX __will__ block by default if output is going to a TTY
(a terminal).
5. Windows functionality differs. Writes block except when output is going to a
TTY.

Additionally, `process.stderr` and `process.stdout` are blocking when outputting
to TTYs (terminals) on OS X as a workaround for the OS's very small, 1kb
buffer size. This is to prevent interleaving between `stdout` and `stderr`.
To check if Node.js is being run in a TTY context, read the `isTTY` property
on `process.stderr`, `process.stdout`, or `process.stdin`:

## process.stdin

Expand Down Expand Up @@ -1482,11 +1486,17 @@ console.log = (msg) => {
};
```

`process.stderr` and `process.stdout` are unlike other streams in Node.js in
that they cannot be closed (calling [`end()`][] will throw an Error), they never
emit the [`'finish'`][] event and that writes can block when output is
redirected to a file (although disks are fast and operating systems normally
employ write-back caching so it should be a very rare occurrence indeed.)
Note: `process.stderr` and `process.stdout` differ from other Node.js streams
in several ways:
1. They cannot be closed ([`end()`][] will throw).
2. They never emit the [`'finish'`][] event.
3. Writes _can_ block when output is redirected to a file.
- Note that disks are fast and operating systems normally employ write-back
caching so this is very uncommon.
Copy link
Contributor

Choose a reason for hiding this comment

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

There are two sentences here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@thefourtheye Pardon? Could you elaborate?

Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't there be a comma or semicolon before so?

4. Writes on UNIX __will__ block by default if output is going to a TTY
(a terminal).
5. Windows functionality differs. Writes block except when output is going to a
TTY.

To check if Node.js is being run in a TTY context, read the `isTTY` property
on `process.stderr`, `process.stdout`, or `process.stdin`:
Expand Down
7 changes: 7 additions & 0 deletions doc/node.1
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ Path to the file used to store the persistent REPL history. The default path
is ~/.node_repl_history, which is overridden by this variable. Setting the
value to an empty string ("" or " ") disables persistent REPL history.

.TP
.BR NODE_TTY_UNSAFE_ASYNC=1
When set to 1, writes to stdout and stderr will be non-blocking and asynchronous
when outputting to a TTY on platforms which support async stdio.
Setting this will void any guarantee that stdio will not be interleaved or
dropped at program exit. \fBAvoid use.\fR


.SH RESOURCES AND DOCUMENTATION

Expand Down
4 changes: 2 additions & 2 deletions lib/tty.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ function WriteStream(fd) {
writable: true
});

// Prevents interleaved stdout/stderr output in OS X terminals.
// Prevents interleaved or dropped stdout/stderr output for terminals.
// As noted in the following reference, local TTYs tend to be quite fast and
// this behaviour has become expected due historical functionality on OS X,
// even though it was originally intended to change in v1.0.2 (Libuv 1.2.1).
// Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671
if (process.platform === 'darwin') this._handle.setBlocking(true);
this._handle.setBlocking(process.env.NODE_TTY_UNSAFE_ASYNC !== '1');
Copy link
Member

Choose a reason for hiding this comment

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

Setting a const at module load would be microscopically faster :-)


var winSize = [];
var err = this._handle.getWindowSize(winSize);
Expand Down