mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
worker: support MessagePort to workers data
PR-URL: https://github.com/nodejs/node/pull/32278 Fixes: https://github.com/nodejs/node/issues/32250 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
committed by
Anna Henningsen
parent
579e6b95ae
commit
ff2f47d786
@@ -513,6 +513,9 @@ if (isMainThread) {
|
||||
<!-- YAML
|
||||
added: v10.5.0
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/32278
|
||||
description: The `transferList` option was introduced.
|
||||
- version: v13.12.0
|
||||
pr-url: https://github.com/nodejs/node/pull/31664
|
||||
description: The `filename` parameter can be a WHATWG `URL` object using
|
||||
|
||||
@@ -183,6 +183,11 @@ class Worker extends EventEmitter {
|
||||
this[kParentSideStdio] = { stdin, stdout, stderr };
|
||||
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
const transferList = [port2];
|
||||
// If transferList is provided.
|
||||
if (options.transferList)
|
||||
transferList.push(...options.transferList);
|
||||
|
||||
this[kPublicPort] = port1;
|
||||
this[kPublicPort].on('message', (message) => this.emit('message', message));
|
||||
setupPortReferencing(this[kPublicPort], this, 'message');
|
||||
@@ -198,7 +203,7 @@ class Worker extends EventEmitter {
|
||||
require('internal/process/policy').src :
|
||||
null,
|
||||
hasStdin: !!options.stdin
|
||||
}, [port2]);
|
||||
}, transferList);
|
||||
// Actually start the new thread now that everything is in place.
|
||||
this[kHandle].startThread();
|
||||
}
|
||||
|
||||
60
test/parallel/test-worker-workerdata-messageport.js
Normal file
60
test/parallel/test-worker-workerdata-messageport.js
Normal file
@@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
const {
|
||||
Worker, MessageChannel
|
||||
} = require('worker_threads');
|
||||
|
||||
const channel = new MessageChannel();
|
||||
const workerData = { mesage: channel.port1 };
|
||||
const transferList = [channel.port1];
|
||||
const meowScript = () => 'meow';
|
||||
|
||||
{
|
||||
// Should receive the transferList param.
|
||||
new Worker(`${meowScript}`, { eval: true, workerData, transferList });
|
||||
}
|
||||
|
||||
{
|
||||
// Should work with more than one MessagePort.
|
||||
const channel1 = new MessageChannel();
|
||||
const channel2 = new MessageChannel();
|
||||
const workerData = { message: channel1.port1, message2: channel2.port1 };
|
||||
const transferList = [channel1.port1, channel2.port1];
|
||||
new Worker(`${meowScript}`, { eval: true, workerData, transferList });
|
||||
}
|
||||
|
||||
{
|
||||
const uint8Array = new Uint8Array([ 1, 2, 3, 4 ]);
|
||||
assert.deepStrictEqual(uint8Array.length, 4);
|
||||
new Worker(`
|
||||
const { parentPort, workerData } = require('worker_threads');
|
||||
parentPort.postMessage(workerData);
|
||||
`, {
|
||||
eval: true,
|
||||
workerData: uint8Array,
|
||||
transferList: [uint8Array.buffer]
|
||||
}).on(
|
||||
'message',
|
||||
(message) =>
|
||||
assert.deepStrictEqual(message, Uint8Array.of(1, 2, 3, 4))
|
||||
);
|
||||
assert.deepStrictEqual(uint8Array.length, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// Should throw on non valid transferList input.
|
||||
const channel1 = new MessageChannel();
|
||||
const channel2 = new MessageChannel();
|
||||
const workerData = { message: channel1.port1, message2: channel2.port1 };
|
||||
assert.throws(() => new Worker(`${meowScript}`, {
|
||||
eval: true,
|
||||
workerData,
|
||||
transferList: []
|
||||
}), {
|
||||
code: 'ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST',
|
||||
message: 'MessagePort was found in message but not listed in transferList'
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user