Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Send binary data via ChildProcess.send #5727

Closed
EugenDueck opened this issue Jun 21, 2013 · 5 comments
Closed

Send binary data via ChildProcess.send #5727

EugenDueck opened this issue Jun 21, 2013 · 5 comments

Comments

@EugenDueck
Copy link

Is there a way to send binary data efficiently to a child process using (something as easy to use as) ChildProcess.send? send(buf) does not work as expected:

var cluster = require('cluster');

if (cluster.isWorker)
{
  process.on('message', function messageHandler(msg)
  {
    console.log("msg: " + JSON.stringify(msg) +
        " - type: " + typeof msg +
        " - buf? " + Buffer.isBuffer(msg));
  });
}
else
{
  var buffer = new Buffer(2);
  buffer[0] = 5;
  buffer[1] = 88; 
  var worker = cluster.fork();
  worker.on("online", function() { worker.send(buffer); });
}

The above will log

msg: [5,88] - type: object - buf? false

msg turns out to be a JSONified version of the original buffer.

@rlidwka
Copy link

rlidwka commented Jun 21, 2013

Same thing with dates... I'm not sure it's a bug because send() indeed uses JSON internally, and JSON has no easy way to represent buffers.

@bnoordhuis
Copy link
Member

As pointed out by @rlidwka, the control channel speaks JSON. You can only send over things that have a valid JSON representation, something Buffer and Date objects don't really have.

Is there a way to send binary data efficiently to a child process

You can open an additional pipe when spawning the child process:

var args = [ /* ... */ ];
var options = { stdio: ['pipe','pipe','pipe','pipe'] };  // first three are stdin/out/err
var proc = child_process.spawn(cmd, args, options);
var pipe = proc.stdio[3];
pipe.write(Buffer('hello'));

The child can open the pipe like this:

var pipe = new net.Socket({ fd: 3 });
pipe.on('data', function(buf) {
  // do whatever
});

@EugenDueck
Copy link
Author

Thanks bnoordhuis, please consider my pull request that exports some of the configurability of child_process.spawn() to cluster.fork(), via child_process.fork(). It can be used similar to your example, only using cluster instead of child_process. The parent part would look something like this, the child/worker part isn't changed:

var cluster = require('cluster');
var worker = cluster.fork(undefined, { addStdio: ['pipe'] });
var pipe = worker.process.stdio[4];
pipe.write(Buffer('hello'));

I wasn't sure how to handle the env parameter in cluster.fork(), my patch essentially makes it "mandatory", hence the need to pass in "undefined" in the example above. As both are of type object, I couldn't just do an if (Array.isArray(argument[0]) style of argument overload detection.

gibfahn pushed a commit to ibmruntimes/node that referenced this issue Apr 26, 2016
test/parallel/test-regress-GH-5727 assumed that one of the
servers would be listening on IPv6. This breaks when the machine
running the test doesn't have IPv6. This commit builds the
connection key that is compared dynamically.

Refs: nodejs/node#5732
PR-URL: nodejs/node#6319
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
gibfahn pushed a commit to ibmruntimes/node that referenced this issue Apr 27, 2016
test/parallel/test-regress-GH-5727 assumed that one of the
servers would be listening on IPv6. This breaks when the machine
running the test doesn't have IPv6. This commit builds the
connection key that is compared dynamically.

Refs: nodejs/node#5732
PR-URL: nodejs/node#6319
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
@InfinitiesLoop
Copy link

I don't suppose there's been any improvement to this. I would have loved to see the PR for fork options make it, because I cannot seem to figure out a good way of opening this additional IPC channel without having to basically re-implement everything the cluster module is doing for me. Is there a way to set up the IPC channel after the worker has been forked?

@foo123
Copy link

foo123 commented Jul 21, 2016

So is there a way to pass binary data (e.g typed arrays) to forked (not spawned) child process through process.send?

The use case i have, is an image processing lib (for node, browser and web workers) and i have everything working perfect in all platforms except parallel processing in node (through forked child processes), since typed arrays (i.e image data) are serialised as objects, not even arrays.

cjihrig added a commit to nodejs/node that referenced this issue Jul 22, 2016
This commit allows child_process.fork() to pass stdio options
to spawn(). This allows fork() to more easily take advantage of
additional stdio channels.

Refs: nodejs/node-v0.x-archive#5727
PR-URL: #7811
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Minwoo Jung <jmwsoft@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
cjihrig added a commit to cjihrig/node that referenced this issue Aug 1, 2016
This commit allows setupMaster() to configure the stdio channels
for worker processes.

Refs: nodejs/node-v0.x-archive#5727
Refs: nodejs#7811
PR-URL: nodejs#7838
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
cjihrig added a commit to nodejs/node that referenced this issue Aug 10, 2016
This commit allows child_process.fork() to pass stdio options
to spawn(). This allows fork() to more easily take advantage of
additional stdio channels.

Refs: nodejs/node-v0.x-archive#5727
PR-URL: #7811
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Minwoo Jung <jmwsoft@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
cjihrig added a commit to nodejs/node that referenced this issue Aug 10, 2016
This commit allows setupMaster() to configure the stdio channels
for worker processes.

Refs: nodejs/node-v0.x-archive#5727
Refs: #7811
PR-URL: #7838
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
jBarz pushed a commit to ibmruntimes/node that referenced this issue Aug 8, 2017
Removed common.PORT from test-regress-nodejsGH-5051 and
test-regress-nodejsGH-5727 in order to eliminate the possibility
of port collision.

Refs: nodejs/node#12376
PR-URL: nodejs/node#12639
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Yuta Hiroto <hello@about-hiroppy.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants