Node: worker_threads: `Buffer` message silently casted to `Uint8Array`

Created on 16 Apr 2019  路  5Comments  路  Source: nodejs/node

  • Version: v11.14.0
  • Platform: Linux LAPTOP-A0NTIMCN 4.4.0-18362-Microsoft #1-Microsoft Mon Mar 18 12:02:00 PST 2019 x86_64 GNU/Linux
  • Subsystem: worker_threads

worker.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.

question worker

All 5 comments

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_threads where 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, Buffer objects will be read as plain Uint8Arrays on 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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danialkhansari picture danialkhansari  路  3Comments

akdor1154 picture akdor1154  路  3Comments

mcollina picture mcollina  路  3Comments

vsemozhetbyt picture vsemozhetbyt  路  3Comments

danielstaleiny picture danielstaleiny  路  3Comments