lib: fix process.send() sync i/o regression#774
lib: fix process.send() sync i/o regression#774bnoordhuis wants to merge 1 commit intonodejs:v1.xfrom
Conversation
|
The CI run seems to be conflicting with an already running one. I'll resubmit it in a bit. |
|
Running those changes on my 10.9.5 mac laptop: I get tons of failed tests for some reason, all with either TIMEDOUT errors or with ENOSYS such as the following. While trying the use case as given in #760, I get the following error (much alike the test failing errors): |
|
@brendanashworth are you sure you have the uv upgrade patch applied? |
|
@saghul oop, you're right, I needed to update my master before I branched to test this - my fault. On my system this now fixes it. <3 Besides the |
There was a problem hiding this comment.
is there a reason typeof(msg) is used here instead of typeof msg? I usually see the latter in the codebase
There was a problem hiding this comment.
No reason. In my head it's more of a function call than an operator. I'll drop the parens before I land it.
process.send() should be synchronous, i.e. it should block until the message has been sent in full, but it wasn't after the second-to-last libuv upgrade because of commit libuv/libuv@393c1c5 ("unix: set non-block mode in uv_{pipe,tcp,udp}_open"), which made its way into io.js in commit 07bd05b ("deps: update libuv to 1.2.1"). Commit libuv/libuv@b36d4ff ("unix: implement uv_stream_set_blocking()") as landed in io.js in commit 9681fca ("deps: update libuv to 1.4.0") makes it possible to restore the synchronous behavior again and that's precisely what this commit does. PR-URL: nodejs/node#774 Reviewed-by: Trevor Norris <[email protected]>
process.send() should be synchronous, it should block until the message has been sent in full, but it wasn't after the second-to-last libuv upgrade because of commit libuv/libuv@393c1c5 ("unix: set non-block mode in uv_{pipe,tcp,udp}_open"), which made its way into io.js in commit 07bd05b ("deps: update libuv to 1.2.1"). Commit libuv/libuv@b36d4ff ("unix: implement uv_stream_set_blocking()") as landed in io.js in commit 9681fca ("deps: update libuv to 1.4.0") makes it possible to restore the synchronous behavior again and that's precisely what this commit does. The same line of reasoning applies to `net.Socket({ fd: 1 })`: creating a socket object from a stdio file descriptor, like the `process.stdout` getter does, should put the file descriptor in blocking mode for compatibility reasons. Fixes: nodejs#760 Fixes: nodejs#784
f366417 to
1fea458
Compare
|
Updated with the feedback from #784. PTAL @brendanashworth @vkurchatkin. https://jenkins-iojs.nodesource.com/view/iojs/job/iojs+any-pr+multi/163/ |
|
LGTM |
|
@piscisaureus mentioned in passing something about blocking mode being unsafe on Windows but without going into details. I've asked him to chime in. |
|
I haven't run the tests but the code looks great to me. |
process.send() should be synchronous, it should block until the message has been sent in full, but it wasn't after the second-to-last libuv upgrade because of commit libuv/libuv@393c1c5 ("unix: set non-block mode in uv_{pipe,tcp,udp}_open"), which made its way into io.js in commit 07bd05b ("deps: update libuv to 1.2.1"). Commit libuv/libuv@b36d4ff ("unix: implement uv_stream_set_blocking()") as landed in io.js in commit 9681fca ("deps: update libuv to 1.4.0") makes it possible to restore the synchronous behavior again and that's precisely what this commit does. The same line of reasoning applies to `net.Socket({ fd: 1 })`: creating a socket object from a stdio file descriptor, like the `process.stdout` getter does, should put the file descriptor in blocking mode for compatibility reasons. PR-URL: nodejs/node#774 Reviewed-by: Trevor Norris <[email protected]>
|
On windows, process.send() has always been async. This bothers me and I wouldn't mind fixing it, but be aware that changing this now amounts to an API change. Doing synchronous writes to a pipe that's open in "overlapped" mode is currently not supported by libuv, we'd have to add support for it. |
|
@piscisaureus this is one of those areas where its not clear. this could be called a major revision/api change, or it could be called a bug that windows is not same as linux, and only a patch... It could also be considered a regression, because maybe unix should be async on process.send (and stdout/err), and this goes the other way. I don't have strong feelings. Its hard to know how many users depend on this sync feature on windows. I'd be tempted to call it a bug fix, for now, and make async on both in the next major (or streaming... but that's lots of work). |
process.send() should be synchronous, it should block until the message has been sent in full, but it wasn't after the second-to-last libuv upgrade because of commit libuv/libuv@393c1c5 ("unix: set non-block mode in uv_{pipe,tcp,udp}_open"), which made its way into io.js in commit 07bd05b ("deps: update libuv to 1.2.1"). Commit libuv/libuv@b36d4ff ("unix: implement uv_stream_set_blocking()") as landed in io.js in commit 9681fca ("deps: update libuv to 1.4.0") makes it possible to restore the synchronous behavior again and that's precisely what this commit does. The same line of reasoning applies to `net.Socket({ fd: 1 })`: creating a socket object from a stdio file descriptor, like the `process.stdout` getter does, should put the file descriptor in blocking mode for compatibility reasons. PR-URL: nodejs/node#774 Reviewed-by: Trevor Norris <[email protected]>
|
In the
With that, I'd say that Windows being async would be a bug and should be a patch. Plus, since |
|
Let's discuss at the next TC meeting.
That might be problematic, it sounds like it could break the child_process module. The libuv documentation for uv_pipe_open() doesn't mention that limitation, by the way. |
|
@brendanashworth the cluster docs you link to say |
process.send() should be synchronous, it should block until the message has been sent in full, but it wasn't after the second-to-last libuv upgrade because of commit libuv/libuv@393c1c5 ("unix: set non-block mode in uv_{pipe,tcp,udp}_open"), which made its way into io.js in commit 07bd05b ("deps: update libuv to 1.2.1"). Commit libuv/libuv@b36d4ff ("unix: implement uv_stream_set_blocking()") as landed in io.js in commit 9681fca ("deps: update libuv to 1.4.0") makes it possible to restore the synchronous behavior again and that's precisely what this commit does. The same line of reasoning applies to `net.Socket({ fd: 1 })`: creating a socket object from a stdio file descriptor, like the `process.stdout` getter does, should put the file descriptor in blocking mode for compatibility reasons. PR-URL: nodejs/node#774 Reviewed-by: Trevor Norris <[email protected]>
|
status? this is going back into "known issues" for 1.3.0 where we mentioned that a fix should "appear in the next patch release" (my words I think, sorry). |
|
If the send is synchronous, does that mean it also waits in the receiver to process the message or just the sending side blocks to perform the send to the kernel? |
|
The latter. There is no guarantee the receiver actually received it (or will receive it - the message is lost when the process goes away.) |
|
I did a simple merge of this and the latest master and ran a CI @ https://jenkins-iojs.nodesource.com/job/iojs+any-pr+multi/632/ on my branch and got a bunch of failures on windows:
/cc @piscisaureus |
|
This is going to slip for the 2.0 release as decided on the TC meeting on 4/29. Removing it from the milestone. |
|
@bnoordhuis will you have time to update this soon? |
|
I think I'd rather take a different approach and make the asynchronous nature of process.send() official. |
|
There will be a huge pain to my application if That being said, I suggest to let this method asynchronously by default .Synchronous message exchange should be applied via a flag or even another |
|
Just curious: how well it will perform while being async? Also, I think there are many userland modules, that are basically meant to do same thing as |
|
Performance-wise, it probably doesn't matter much if process.send() is synchronous or not; with most workloads, JSON.parse and JSON.stringify are the biggest cost centers. |
|
Closing, possibly to be rediscussed in #34 |
process.send() should be synchronous, i.e. it should block until the
message has been sent in full, but it wasn't after the second-to-last
libuv upgrade because of commit libuv/libuv@393c1c5 ("unix: set
non-block mode in uv_{pipe,tcp,udp}_open"), which made its way into
io.js in commit 07bd05b ("deps: update libuv to 1.2.1").
Commit libuv/libuv@b36d4ff ("unix: implement uv_stream_set_blocking()")
as landed in io.js in commit 9681fca ("deps: update libuv to 1.4.0")
makes it possible to restore the synchronous behavior again and that's
precisely what this commit does.
Fixes: #760
R=@brendanashworth @piscisaureus
On Windows, this sets the UV_HANDLE_BLOCKING_WRITES flag on the handle. I'd like @piscisaureus to confirm whether that's harmless or not.
https://jenkins-iojs.nodesource.com/view/iojs/job/iojs+any-pr+multi/160/