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

Conversation

Fishrock123
Copy link
Contributor

@Fishrock123 Fishrock123 commented May 17, 2016

Checklist
  • tests and code linting passes
  • a test and/or benchmark is included
  • documentation is changed or added
  • the commit message follows commit guidelines
Affected core subsystem(s)

tty, process

Description of change

See discussion at:

cc @nodejs/ctc @isaacs @ksc @saghul etc

Note: we still have more investigation to do but this is looking like it is probably the correct thing to do.

@nodejs-github-bot nodejs-github-bot added the tty Issues and PRs related to the tty subsystem. label May 17, 2016
@indutny
Copy link
Member

indutny commented May 17, 2016

I have a deja vu here... Is it like 3rd time we re-enable it?

@indutny
Copy link
Member

indutny commented May 17, 2016

Am I right that running node script.js | some-prog-that-does-not-read-stdin will make script.js eventually hang on writes?

@addaleax
Copy link
Member

@indutny This should only affect ttys, so, no, I don’t think so.

@indutny
Copy link
Member

indutny commented May 17, 2016

@addaleax oh, right! Thank you. LGTM then, I have no issues with this.

@mscdex
Copy link
Contributor

mscdex commented May 17, 2016

Shouldn't there at least be an official way to change the behavior (in case someone needs/wants async)?

@Fishrock123
Copy link
Contributor Author

I have a deja vu here... Is it like 3rd time we re-enable it?

Haha, not quite. ;)

@mscdex Official? Idk. But you can still do tty._handle.setBlocking(false) afaik.

That being said, I can't think of a reason you'd need async in a TTY? Maybe if only one stream is to a TTY?

@mscdex
Copy link
Contributor

mscdex commented May 17, 2016

@Fishrock123 I meant a way without accessing an underscored property.

@saghul
Copy link
Member

saghul commented May 17, 2016

LGTM. (fingers crossed so we don't open a can of worms).

/cc @bnoordhuis I believe this whole thing make some sense in your brain, I'd love to see your yay or nay here.

jasnell added a commit to jasnell/node that referenced this pull request May 17, 2016
Builds on nodejs#6816,
adds API for explicitly setting non-blocking mode
without relying on `_`-prefixed internal property.

Adds documentation.
@jasnell
Copy link
Member

jasnell commented May 17, 2016

@mscdex ... like this? jasnell@4982550

@jasnell
Copy link
Member

jasnell commented May 17, 2016

This PR should include a documentation update that (a) describes the default behavior of tty.ReadStream and (b) demonstrates a supported way of making it unblocking. I'm not comfortable with this landing until at least (a) is added.

@Fishrock123
Copy link
Contributor Author

Fishrock123 commented May 17, 2016

@jasnell So, there are a couple issues with your API proposal.

The biggest is that actually creating TTY streams isn't particularly supported:

In normal circumstances, process.stdout will be the only tty.WriteStream instance ever created (and only when isatty(1) is true).

In fact, I've tried to make tty streams before and found it's virtually impossible. You can only make one if the fd is a tty and it is not already in use, which is basically never. I actually don't know of a case when you could ever make one manually without severe hackery.

However, exposing a setBlocking method publicly also causes some concerns:

  1. The existing problem that stdio streams do not have consistent APIs depending on the stream type is yet again amplified (very difficult to fix)
  2. It doesn't work for pipes, but putting this functionality into net.Socket publicly is harmful because of TCP connections.
  3. I'm not sure unblocking is ever valuable for this, in any manor that isn't strictly theoretical.
    • Same goes for pipes, where blocking only has theoretical niceties.

describes the default behavior of tty.ReadStream

I doubt that is useful due to the above, or the correct place to put it, since no-one will go looking for the TTY module from console.log() or process.std{in|out|err}.

I will add a note to where the existing note is for file piping though: https://nodejs.org/dist/latest-v6.x/docs/api/process.html#process_process_stderr

@Fishrock123 Fishrock123 added the process Issues and PRs related to the process subsystem. label May 17, 2016
@Fishrock123 Fishrock123 force-pushed the stdio-TTY-blocking branch from c3bfcb0 to 5645984 Compare May 17, 2016 20:03
@Fishrock123
Copy link
Contributor Author

Updated with docs note.

- (Although disks are fast and operating systems normally employ write-back
caching so this is very uncommon.)
4. Writes __will__ block by default if output is going to a TTY (a terminal) or
Node.js is running on windows.
Copy link
Member

Choose a reason for hiding this comment

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

nit: It’s usually stylized as Windows in the docs.

@Fishrock123 Fishrock123 force-pushed the stdio-TTY-blocking branch from 5645984 to 8a33b16 Compare May 17, 2016 20:06
@addaleax
Copy link
Member

LGTM

@Fishrock123 Fishrock123 force-pushed the stdio-TTY-blocking branch from 8a33b16 to 2504cf5 Compare May 17, 2016 20:08
@mscdex
Copy link
Contributor

mscdex commented May 17, 2016

@jasnell Something like that would be ideal of course, but even if there was a way to simply change the behavior once on startup. I'm not sure what that would look like or if enough people would be interested in supporting something like that though ...

@jasnell
Copy link
Member

jasnell commented May 17, 2016

@mscdex ... I'm definitely for it (either API or command line switch) but given the discussion I doubt we'd get consensus to add it so I'm going to just drop it.

@jasnell
Copy link
Member

jasnell commented May 17, 2016

I would say that this looks like a semver-major change but I know there will be disagreement with that.

@addaleax
Copy link
Member

addaleax commented May 17, 2016

@jasnell Could you give an example of what you imagine might break because of this change?

@Fishrock123
Copy link
Contributor Author

I can imagine a lot of things that are already breaking without this change. ;)

@Fishrock123
Copy link
Contributor Author

@jasnell @mscdex I'd be open to it if there is actually a reason to do it, but no reasons are appearing...?

@jasnell
Copy link
Member

jasnell commented May 17, 2016

@addaleax ... not off hand but it is a change in the established default behavior, which would technically qualify it as a semver-major. Note that I didn't add the label ;-) ... I'm quite certain that I'm in the minority.

@Fishrock123
Copy link
Contributor Author

but it is a change in the established default behavior,

Sorta. It gets tricky here because on OS X it appears to have previously actually blocked when it wasn't supposed to so the majority of the CLI users never noticed this because it never changed on their platform sooner. So... the previous behavior is actually more established there, and due to previous versions of node.js, also across the board I think. Additionally, I'm unsure if console.log() blocks in the browser but I would not be particularly surprised if it did.

@mscdex
Copy link
Contributor

mscdex commented May 17, 2016

I'm more inclined to say semver-major too since the non-blocking behavior in general has existed for quite a long time now in node, so I don't view this change as a "oops we just introduced a bug, let's fix it quickly" kind of situation. shrug

@addaleax
Copy link
Member

As far as I can tell, the only visible difference would be in timing, no? And unlike with pipes, for ttys there is (in 99.99 % of practically occurring situations) an active consumer on the other end, so writing won’t block indefinitely because of this.

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 a couple ways:
Copy link
Member

Choose a reason for hiding this comment

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

Same nits as above.

@Trott
Copy link
Member

Trott commented Jul 15, 2016

Left some nits on the documentation prose, but nothing that I think must happen before landing. (In other words: Don't interpret my nits as me objecting to this landing.)

@MylesBorins
Copy link
Contributor

@Fishrock123 is this something that should be included in v4.5.0?

@saghul
Copy link
Member

saghul commented Jul 16, 2016

@kzc A note to remember: when stdio was made blocking on macOS that was meant to restore the behavior aas in v4.x On other Unix systems it never blocked. We are changing that now. Is it a good or a bad thing? I no longer know.

@kzc
Copy link

kzc commented Jul 16, 2016

@saghul I know the history well. The blocking on Mac was initially inadvertently introduced as result of a bug pre-node 4.x when trying to re-open the tty - ironically to not block stdio - and somehow this blocking stdio behavior on Mac became grandfathered as the status quo.

Whether this PR is good or bad, it just addresses that inconsistency on UNIX platforms. #6816 (comment) sums up my view. Blocking stdio tty alone is not enough to fix the many long standing problems with node stdio. Something like #6773 is still needed to resolve truncated piped stdout/stderr and some similar fix is still required to flush piped stdio in the event of an uncaught exception. Once node is in the process of an abrupt exit and the event loop is no longer running (although not destroyed) there's zero downside to flushing stdout and stderr as users would reasonably expect.

As I don't watch these node issue/PR threads any longer please use my @ handle if you want to get any other feedback.

@saghul
Copy link
Member

saghul commented Jul 17, 2016

@kzc Sure, I know we are currently not in a very good place. Thanks for your efforts so far.

@Fishrock123
Copy link
Contributor Author

@thealphanerd Give it's potentially debatable if this is a major, I'm going to say no.

@Fishrock123
Copy link
Contributor Author

I consider it a non-breaking bugfix given that:

  • There are no shortage of complaints about the current behavior
  • There is no evidence this could cause problems

@Fishrock123
Copy link
Contributor Author

New CI: https://ci.nodejs.org/job/node-test-pull-request/3324/

@jasnell Could you take a look at this again and let us know if you are comfortable with it?

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.
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

@jasnell
Copy link
Member

jasnell commented Jul 20, 2016

LGTM but we'll need to message this properly. While I believe there is consensus around landing this as a bug fix, it is technically a fairly significant change in behavior that should technically be tagged as a semver-major. There should be a release candidate cycle for any release that this goes out in just to be on the safe side.

@Fishrock123
Copy link
Contributor Author

Fishrock123 commented Jul 21, 2016

If it must land in a semver-major, it could.

I do not think it is reasonable to see this as an API change however, so I think it may be worth our while to get this in before v6 goes LTS.

@addaleax
Copy link
Member

addaleax commented Aug 8, 2016

This still LGTM, and I’m still +1 on not seeing this as a semver-major because afaict, this doesn’t necessarily represent a visible behavioural change.

@Fishrock123
Copy link
Contributor Author

Guess we're clear to land... or as clear as it will get.

@jasnell how do you propose we message it?

@jasnell
Copy link
Member

jasnell commented Aug 8, 2016

Twitter PSA at the very least (I can do that in just a minute). Even tho this will land as a patch, we need to make sure it's called out explicitly in the release notes. Beyond that, I'm not sure what else.

@jasnell
Copy link
Member

jasnell commented Aug 8, 2016

I would definitely recommend that we do a release candidate for whatever release this lands in.

@addaleax
Copy link
Member

addaleax commented Aug 10, 2016

I’ll be landing this later today if there are no objections and nobody else does before me, this has been lying around long enough.

edit: One more CI: https://ci.nodejs.org/job/node-test-commit/4501/

@addaleax
Copy link
Member

Landed in ab3306a

@addaleax addaleax closed this Aug 10, 2016
addaleax pushed a commit that referenced this pull request Aug 10, 2016
Refs: #1771
Refs: #6456
Refs: #6773
Refs: #7743
PR-URL: #6816
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Saúl Ibarra Corretgé <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Rod Vagg <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: James M Snell <[email protected]>
cjihrig pushed a commit that referenced this pull request Aug 11, 2016
Refs: #1771
Refs: #6456
Refs: #6773
Refs: #7743
PR-URL: #6816
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Saúl Ibarra Corretgé <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Rod Vagg <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: James M Snell <[email protected]>
@cjihrig cjihrig mentioned this pull request Aug 11, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
process Issues and PRs related to the process subsystem. tty Issues and PRs related to the tty subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.