-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
fix(node): Rework node:child_process IPC #24763
Conversation
@@ -1050,10 +1050,10 @@ impl CliOptions { | |||
} | |||
|
|||
pub fn node_ipc_fd(&self) -> Option<i64> { | |||
let maybe_node_channel_fd = std::env::var("DENO_CHANNEL_FD").ok(); | |||
let maybe_node_channel_fd = std::env::var("NODE_CHANNEL_FD").ok(); |
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.
@littledivy just to be sure, we went with DENO_CHANNEL_FD
because we couldn't communicate between Node.js and Deno subprocesses, right?
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.
yup, this PR seems to enable Deno processes spawned by Node processes to communicate. @nathanwhit is it also working the other way around?
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.
Yup, at least on unix (haven't tested windows). Though sending handles won't work (bc we don't support it yet).
@@ -53,25 +163,66 @@ mod impl_ { | |||
Some(child_pipe_fd) => child_pipe_fd.0, | |||
None => return Ok(None), | |||
}; | |||
|
|||
let ref_tracker = IpcRefTracker::new(state.external_ops_tracker.clone()); |
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.
Not for this PR, but I think we should move most of this module to runtime/ops
or even create a separate deno_ipc
crate. Besides the serialization code it seems abstract enough that we could expose an IPC API for Deno.Command
API.
c08627b
to
34b4115
Compare
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, really nice work!
Fixes #24756. Fixes #24796. This also gets vitest working when using [`--pool=forks`](https://vitest.dev/guide/improving-performance#pool) (which is the default as of vitest 2.0). Ref #23882. --- This PR resolves a handful of issues with child_process IPC. In particular: - We didn't support sending typed array views over IPC - Opening an IPC channel resulted in the event loop never exiting - Sending a `null` over IPC would terminate the channel - There was some UB in the read implementation (transmuting an `&[u8]` to `&mut [u8]`) - The `send` method wasn't returning anything, so there was no way to signal backpressure (this also resulted in the benchmark `child_process_ipc.mjs` being misleading, as it tried to respect backpressure. That gave node much worse results at larger message sizes, and gave us much worse results at smaller message sizes). - We weren't setting up the `channel` property on the `process` global (or on the `ChildProcess` object), and also didn't have a way to ref/unref the channel - Calling `kill` multiple times (or disconnecting the channel, then calling kill) would throw an error - Node couldn't spawn a deno subprocess and communicate with it over IPC (cherry picked from commit cd59fc5)
Fixes #24756. Fixes #24796.
This also gets vitest working when using
--pool=forks
(which is the default as of vitest 2.0). Ref #23882.This PR resolves a handful of issues with child_process IPC. In particular:
null
over IPC would terminate the channel&[u8]
to&mut [u8]
)send
method wasn't returning anything, so there was no way to signal backpressure (this also resulted in the benchmarkchild_process_ipc.mjs
being misleading, as it tried to respect backpressure. That gave node much worse results at larger message sizes, and gave us much worse results at smaller message sizes).channel
property on theprocess
global (or on theChildProcess
object), and also didn't have a way to ref/unref the channelkill
multiple times (or disconnecting the channel, then calling kill) would throw an error