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

Stdin becomes paused at close only when using StdinDiscarder with TTY #209

Open
clavin opened this issue Jun 24, 2022 · 2 comments · Fixed by #210
Open

Stdin becomes paused at close only when using StdinDiscarder with TTY #209

clavin opened this issue Jun 24, 2022 · 2 comments · Fixed by #210

Comments

@clavin
Copy link
Contributor

clavin commented Jun 24, 2022

When ora uses its StdinDiscarder, stdin will be paused when the discarder is stopped (on all platforms except windows). This is due to a historic, undocumented implementation detail of node:readline, where calling readline.close() causes the input stream (stdin) to be paused. Thus, this propagates up to StdinDiscarder when it calls close on its readline handle.

I feel like this behavior seems like a bug in ora, unintentionally present due to the side-effect from node:readline. It feels inconsistent that stdin would be paused at the very end of ora's lifecycle only on the condition of using a tty and the StdinDiscarder. I would expect stdin to remain unpaused at the end of ora's lifecycle regardless of those conditions.

@sindresorhus
Copy link
Owner

Reopened because of #211

@clavin
Copy link
Contributor Author

clavin commented Jun 29, 2022

Just to document it, here's another possible solution I tried that ended up a dead end:

Since readline pauses the input stream it's given, I thought why not try giving it a proxy stream of stdin that we can dispose of at the end of StdinDiscarder's lifetime, i.e. using pipe to flow stdin through a PassThrough stream and providing that as the input to readline.

                   [input proxy]
+-------+         +-------------+
| stdin | ------> | PassThrough |
+-------+         +-------------+
                         |
                         v
                       input
                    +----------+
                    | readline |
                    +----------+
                       output
                         |
                         v
+--------+     +------------------+
| stdout | <-- | BufferListStream |
+--------+     +------------------+

That sort of works, but there's an important caveat: when the proxy stream is discarded, either by unpipeing it from stdin or by calling destroy on it, the upstream stdin can become paused if there are no other pipes attached to it. That is, if you have an on('data', ...) event handler on stdin, stdin will become paused; however, if you are still pipeing stdin to another stream and reading from that, stdin will not become paused. The practical difference between unpipe and destory here is that unpipe will try to pause immediately, whereas destroy will try to pause on the next tick.

Ultimately, I decided this solution was too finicky to contribute as it is not significantly better than just calling resume on stdin in user code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants