v11.14.0Linux LAPTOP-A0NTIMCN 4.4.0-18362-Microsoft #1-Microsoft Mon Mar 18 12:02:00 PST 2019 x86_64 GNU/Linuxworker_threadsworker.js:
const { parentPort } = require("worker_threads");
parentPort.postMessage(Buffer.from([2, 3, 5, 7]));
main.js:
const { Worker } = require("worker_threads");
const worker = new Worker("./worker.js");
worker.on("message", msg => {
console.log([msg instanceof Buffer, msg instanceof Uint8Array]);
});
Result of running node main.js:
[ false, true ]
Apparently, a Buffer message was sent from the worker thread, but when received in the main thread it's silently cast to a Uint8Array, which can cause confusion since those two's API don't quite overlap.
Is this a bug or expected behavior? If expected, probably good to document it in the section of worker_threads where structured cloning is explained.
Instanceof checks only work in the same realm. The worker is not the realm in which the buffer was originally created and instanceof can therefore not be used anymore.
The constructor should still be Buffer (log msg.constructor).
It isn't.
Changed main.js:
const { Worker } = require("worker_threads");
const worker = new Worker("./worker.js");
worker.on("message", msg => {
console.log(msg.constructor);
console.log(msg.readUInt8(0));
});
Output:
[Function: Uint8Array]
/mnt/c/Users/Think/Documents/Haskell/asterius/test/main.js:7
console.log(msg.readUInt8(0));
^
TypeError: msg.readUInt8 is not a function
at Worker.worker.on.msg (/mnt/c/Users/Think/Documents/Haskell/asterius/test/main.js:7:19)
at Worker.emit (events.js:193:13)
at MessagePort.Worker.(anonymous function).on (internal/worker.js:137:55)
at MessagePort.emit (events.js:193:13)
at MessagePort.onmessage (internal/worker/io.js:73:8)
@nodejs/workers
Is this a bug or expected behavior?
It is expected behaviour, because structured cloning is specified to work that way.
If expected, probably good to document it in the section of
worker_threadswhere structured cloning is explained.
Fwiw, we do explicitly mention this in https://nodejs.org/api/worker_threads.html#worker_threads_port_postmessage_value_transferlist:
Because the object cloning uses the structured clone algorithm, non-enumerable properties, property accessors, and object prototypes are not preserved. In particular,
Bufferobjects will be read as plainUint8Arrayson the receiving side.
That being said, where would you have looked for this information? A cross-reference might be helpful.
@addaleax Thanks for pointing out; that's exactly where I would have looked for but I seem to have skipped through that paragraph, sorry. Feel free to close this issue.