-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
stream,win: fix ghost keypress events #5776
Conversation
The tty.ReadStream constructor initializes this as a socket, which causes a read to be initiated. Even though during stdin initalization we call readStop shortly after, the read operation can consume keypress events from the system buffers. Fixes: nodejs#5384
Readable.resume() schedules the resume operation onto the next tick, whereas pause() has immediate effect. This means that in a sequence stream.resume(); stream.pause(); .. the 'pause' event will be triggered before the resume operation is performed. For process.stdin, we are relying on the 'pause' event to stop reading on the underlying handle. This fix ensures that reads are started and stopped in the same order as resume() and pause() are called.
LGTM, but would like sign off from a streams person. |
are there any tests that cover pausing and then resuming synchronously ? possibly with data being written between the pause and the resume where the state has changed but the event hasn't been emitted, possibly while streaming to something else (or having data streamed to it) ? |
@orangemocha ... is there any way to add a test? |
What semver rating should this have? |
@jasnell it would be nice to have tests for this sort of things, but it would require some external tooling to generate keystroke events. There are tools that I know work on Windows, I would have to do more research to find out if there are any that work cross platform. I would prefer to defer the general idea of testing console input to @nodejs/testing and not block this PR on it. The ghost keypress input is a bug fix. The 'resume' event is undocumented and the change shouldn't have any semver-major side effects. |
@orangemocha .. +1 |
@calvinmetcalf I think that https://github.com/nodejs/node/blob/master/test/parallel/test-stream3-pause-then-read.js might provide coverage along the lines of what you are describing, in addition to these other tests |
@orangemocha .. is this appropriate for v4? |
@jasnell as described in #5384 (comment) the issue is present in all release lines but it becomes more apparent when node startup is slow, which apparently got exacerbated with a c-ares update. The c-ares updated has not been backported to v4. So I would probably err on the conservative side and not backport it unless we get some reports by v4 users, and not before some bake time in v5 anyway. |
@orangemocha +1 .. sounds good! I'll label with dont-land-on-v4 for now. |
Sounds good! Still looking for a LGTM by a streams person :) |
I've found that this pull-request also fixes #5574, could it be back-ported to Node.js v4.x? That's needed for NodeOS to use the rewritten |
@piranna ... potentially but not yet. I'll add the lts-watch label so this is not forgotten about but as @orangemocha recommended this change will need to sit for a bit in v5 first. |
@jasnell, thanks for the consideration :-) It's ok for me to know this could eventually be added (NodeOS is not ready to move to Node.js 5 and npm3 yet). I've found that I don't get the last fragment of text if I write characters "a bit slow" (less than 5550kpm for a text of 996 characters), I'll try to test this pull-request a little bit more to see if it's a bug in my test before submit it. |
Barring any objections, I am planning to land this on Wednesday. @nodejs/streams , let me know if you would like to review it but need more time. |
The tty.ReadStream constructor initializes this as a socket, which causes a read to be initiated. Even though during stdin initalization we call readStop shortly after, the read operation can consume keypress events from the system buffers. Fixes: #5384 PR-URL: #5776 Reviewed-By: cjihrig - Colin Ihrig <cjihrig@gmail.com> Reviewed-By: jasnell - James M Snell <jasnell@gmail.com>
Readable.resume() schedules the resume operation onto the next tick, whereas pause() has immediate effect. This means that in a sequence stream.resume(); stream.pause(); .. the 'pause' event will be triggered before the resume operation is performed. For process.stdin, we are relying on the 'pause' event to stop reading on the underlying handle. This fix ensures that reads are started and stopped in the same order as resume() and pause() are called. PR-URL: #5776 Reviewed-By: cjihrig - Colin Ihrig <cjihrig@gmail.com> Reviewed-By: jasnell - James M Snell <jasnell@gmail.com>
I've found this pull-request doesn't fix the problem I'm having on Ubuntu 32bits and my test doesn't pass on it, I'm going to do more tests to see if I'm having a Linux-only or a 32bits-only problem. |
I was away from my computer most of this week so apologise for the late reply. Did anyone test the performance implications of this? |
Unfortunately this fix had unwanted consequences: #5927. |
I'm against this fix, in particular the fact that I don't think we should change the stream implementation for fixing a problem on windows. Something else must go on. |
(I'm sorry to jump later on this, but I have been away for the last 10 days). |
The fix is for Windows, but it (partially) fix the problem I have in #5574 too, and I've check that error happens on Linux and OSX. |
This PR changes the behavior of streams to fix a platform specific problem: https://github.com/orangemocha/io.js/blob/f9768a0384acff612666fb12c728c0cac6983706/lib/_stream_readable.js#L742. This is what I question. The fix on windows (and your issue) is probably something different, that does not require changing streams. If you need to change streams, let's discuss it separately, we need to ensure we do not break the API contract entirely, we do not decrease performance, and we do not break modules on NPM. |
Ok, I agree, in my case it seems more a bug fix than a change on the behaviour. |
I agree with @mcollina that we should revert this |
What's the process for reverting something? Maybe the best person to do this is @orangemocha who has the clearer picture. Please cc both @mafintosh and myself. |
Thanks for reverting this change, it obviously needs more work. |
Pull Request check-list
make -j8 test
(UNIX) orvcbuild test nosign
(Windows) pass withthis change (including linting)?
test (or a benchmark) included?
existing APIs, or introduces new ones)?
Affected core subsystem(s)
stream, win
Description of change
First commit:
The tty.ReadStream constructor initializes this as a socket,
which causes a read to be initiated. Even though during stdin
initalization we call readStop shortly after, the read operation
can consume keypress events from the system buffers.
Fixes: #5384
Second commit:
The change in the first commit change surfaces an issue with readable streams, which causes test\parallel\test-stdin-resume-pause.js (and a few others) to fail. The second commit addresses that issue.
R: @nodejs/streams @silverwind @cjihrig