Stdin becomes paused at close only when using `StdinDiscarder` with TTY
clavin opened this issue · 2 comments
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.
Reopened because of #211
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 unpipe
ing it from stdin
or by calling destroy
on it, the upstream stdin
can become paused if there are no other pipe
s attached to it. That is, if you have an on('data', ...)
event handler on stdin
, stdin
will become paused; however, if you are still pipe
ing 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.