-
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
net: emit 'close' after 'end' #19241
Conversation
This is potentially semver-major as the |
This aligns behavior with other Will take a closer look tomorrow |
Yes, at least it aims to do that. |
I think this is semver-major. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
51636f4
to
9c58feb
Compare
CI: https://ci.nodejs.org/job/node-test-pull-request/13601/ |
59e5611
to
6cfc5c8
Compare
@lpinca can you please check that we follow this pattern also in HTTP, HTTP2, fs, etc? Also, |
This is not trivial, it seems to be the case for HTTP but not fs, the
|
@lpinca |
For HTTP/2, |
@mcollina ok, I'll
|
I'm a bit hesitant on adding it to CITGM as it seems to be only tested with |
cc: @mafintosh |
6cfc5c8
to
590abf7
Compare
I would like to land this. It already has 3 TSC approvals but it would be nice to have more opinions. CI: https://ci.nodejs.org/job/node-test-pull-request/13738/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely semver-major, changes lgtm
Currently the writable side of the socket is closed as soon as `UV_EOF` is read regardless of the state of the socket. This allows the handle to be closed before `'end'` is emitted and thus `'close'` can be emitted before `'end'` if the socket is paused. This commit prevents the handle from being closed until `'end'` is emitted ensuring the correct order of events. Fixes: nodejs#19166
Wait for the sockets to be connected before closing them and remove unneeded `setTimeout()`.
590abf7
to
5b957e1
Compare
Landed in 0ac4ef9...9b7a691. |
Wait for the sockets to be connected before closing them and remove unneeded `setTimeout()`. PR-URL: #19241 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Currently the writable side of the socket is closed as soon as `UV_EOF` is read regardless of the state of the socket. This allows the handle to be closed before `'end'` is emitted and thus `'close'` can be emitted before `'end'` if the socket is paused. This commit prevents the handle from being closed until `'end'` is emitted ensuring the correct order of events. PR-URL: #19241 Fixes: #19166 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
@lpinca On redis/ioredis#633 I'm seeing that the socket is not in a paused state (that is, its isPaused() returns false) but does have a If the answer is that this is not an intentional new behavior, I'll try to boil it down to more minimal repro case (one that doesn't involve spinning up a Redis cluster). |
If the socket is still writable it's expected, |
@lpinca Ok, thanks! It looks like what is happening here is that when we connect with a timeout that fires off an
So that causes the socket to never call Does that make sense to you? It may be that I have an incorrect expectation that calling |
@brettkiefer yes it makes sense, this is an interesting race condition. A dirty workaround would be to call |
@lpinca Thanks. that sounds like a good idea. I'll see what IORedis might accept as a workaround and get an issue submitted against Node.js tomorrow (unless you think you can give better context, in which case please feel free) and link it here. I don't immediately see any internal state on the socket that looks appropriate for switching behavior in |
Here is a test case for the issue you are describing: const net = require('net');
const server = net.createServer();
server.listen(() => {
const socket = net.createConnection(server.address().port);
socket.on('connect', () => console.log('connect'));
socket.on('end', () => console.log('end'));
socket.on('close', () => console.log('close'));
socket.end();
}); No |
Currently the writable side of the socket is closed as soon as
UV_EOF
is read regardless of the state of the socket. This allows the handle
to be closed before
'end'
is emitted and thus'close'
can beemitted before
'end'
if the socket is paused.This commit prevents the handle from being closed until
'end'
isemitted ensuring the correct order of events.
Fixes: #19166
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes