Node: SharedArrayBuffer does not serialize/deserialize correctly

Created on 21 Apr 2018  路  7Comments  路  Source: nodejs/node

Version: 9.11.1
Platform: windows 10 64bit
Subsystem: child_process/process/cluster

It is my understanding that SharedArrayBuffer should be serialized/deserialized when sent over an IPC channel to a child_process. This does not appear to be happening. If child_process IPC channels are not the correct approach for using SharedArrayBuffer, what is?

Here are some supporting tests:

SABTest.js

"use strict";

const child_process = require("child_process");

let cp = null;
let count = 0;

const MAX_COUNT = 100;

const next = function() {
    let buf = new SharedArrayBuffer(4);
    let view = new Int32Array(buf);
    view[0] = count;

    console.log("send msg "+count);
    cp.send(buf);

    count += 1;
    if (count>MAX_COUNT) process.exit(0);

    setTimeout(next,10);
};

let init = async function() {
    // start process
    cp = child_process.fork("./SABTestReceiver",[],{
        silent: false
    });

    // wait 250ms for ip channel to setup
    await new Promise((resolve,reject)=>{
        try {
            setTimeout(()=>{
                resolve();
            },250);
        }
        catch (ex) {
            return reject(ex);
        }
    });

    // start sending.
    next();
};

init();

SABTestReceiver.js

"use strict";

process.on("message",(msg)=>{
    console.log("rcvd message...",msg instanceof SharedArrayBuffer,msg instanceof ArrayBuffer,msg instanceof Int32Array,msg);
});

Output from running the above...

send msg 0
rcvd message... false false false {}
send msg 1
rcvd message... false false false {}
send msg 2
rcvd message... false false false {}
...

I also changed from sending the SharedArrayBuffer on line 16 to try sending the TypedArray (Int32Array) and get slightly better results, but the TypedArray is just serialized to a Object.

Output (from sending the TypedArray)

send msg 0
rcvd message... false false false { '0': 0 }
send msg 1
rcvd message... false false false { '0': 1 }
send msg 2
rcvd message... false false false { '0': 2 }
...

Am happy to close if there is some oversight on my part or I'm not using this as intended.

child_process question worker

Most helpful comment

That was the answer I needed. Thank you.

All 7 comments

ipc channels currently use json for communication. i believe the eventual goal is to use our serdes api instead (an implementation of the html structured clone protocol), which will handle far more types, including various types of array buffers

@devsnek To be clear then, you can instantiate SharedArrayBuffer, you just can鈥檛 do anything with it...

@arei i'm sure there are lots of userland things to do with them :)

That you couldn鈥檛 already do with AreayBuffer? The thing that they are specifically intended to solve, shared memory across different workers is not possible...

@arei child processes are not workers. they are separate processes. i should mention that with child_process even when we do change it to use serdes it still won't actually share the arrays, since they will be in separate processes.

node is planning to add actual workers which will probably available at some point

That was the answer I needed. Thank you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

akdor1154 picture akdor1154  路  3Comments

addaleax picture addaleax  路  3Comments

dfahlander picture dfahlander  路  3Comments

willnwhite picture willnwhite  路  3Comments

vsemozhetbyt picture vsemozhetbyt  路  3Comments