Skip to content

Commit

Permalink
worker: implement SHARE_ENV. see nodejs/node#26544.
Browse files Browse the repository at this point in the history
  • Loading branch information
chjj committed Apr 1, 2019
1 parent f317ed0 commit 66f91af
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Some caveats for the `child_process` backend:
do not hold event loop references (`ref()` and `unref()` are noops).
- Prior to node 10, objects like `Proxy`s can be serialized and cloned as they
cannot be detected from regular javascript.
- `SHARE_ENV` does not work and will throw an error if passed.

Caveats for the `web_workers` backend:

Expand All @@ -102,6 +103,7 @@ Caveats for the `web_workers` backend:
depending on your `Content-Security-Policy`.
- `FileList` will emerge on the other side as an `Array` rather than a
`FileList` when sent as `workerData`.
- `SHARE_ENV` does not work and will throw an error if passed.

Caveats for the `polyfill` backend:

Expand Down
4 changes: 3 additions & 1 deletion lib/browser/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function parseEnv(name) {
WORKER_DATA: undefined,
WORKER_STDIN: false,
WORKER_EVAL: false,
WORKER_ENV: {},
WORKER_BOOTSTRAP: null
};
}
Expand All @@ -38,7 +39,8 @@ function parseEnv(name) {
WORKER_DATA: items[1],
WORKER_STDIN: items[2],
WORKER_EVAL: items[3],
WORKER_BOOTSTRAP: items[4]
WORKER_ENV: items[4],
WORKER_BOOTSTRAP: items[5]
};
}

Expand Down
1 change: 1 addition & 0 deletions lib/browser/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ exports.MessagePort = MessagePortBase;
exports.MessageChannel = MessageChannel;
exports.Worker = Worker;
exports.moveMessagePortToContext = null;
exports.SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');
exports.importScripts = null;

exports.backend = backend.polyfill ? 'polyfill' : 'web_workers';
Expand Down
4 changes: 4 additions & 0 deletions lib/browser/parent.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const {
WORKER_ID,
WORKER_DATA,
WORKER_STDIN,
WORKER_ENV,
WORKER_EVAL
} = env;

Expand Down Expand Up @@ -138,6 +139,9 @@ class Parent extends MessagePortBase {
process.stderr = this._stderr;

injectConsole(this._console);

for (const key of Object.keys(WORKER_ENV))
process.env[key] = WORKER_ENV[key];
}

_handleMessage(event) {
Expand Down
1 change: 1 addition & 0 deletions lib/browser/thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ exports.MessagePort = MessagePortBase;
exports.MessageChannel = MessageChannel;
exports.Worker = Worker;
exports.moveMessagePortToContext = null;
exports.SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');
exports.importScripts = importScripts;

exports.backend = backend.polyfill ? 'polyfill' : 'web_workers';
Expand Down
13 changes: 13 additions & 0 deletions lib/browser/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const DEFAULT_BOOTSTRAP_URL =

const BOOTSTRAP_URL = env.WORKER_BOOTSTRAP || DEFAULT_BOOTSTRAP_URL;

const SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');

let uid = 1;

/**
Expand All @@ -68,6 +70,13 @@ class Worker extends EventEmitter {
if (typeof options !== 'object')
throw new ArgError('options', options, 'object');

if (options.env != null
&& typeof options.env !== 'object'
&& options.env !== SHARE_ENV) {
throw new ArgError('env', options.env,
['object', 'worker_threads.SHARE_ENV']);
}

if (options.type != null && typeof options.type !== 'string')
throw new ArgError('type', options.type, 'string');

Expand Down Expand Up @@ -98,6 +107,9 @@ class Worker extends EventEmitter {
let code = null;
let type = options.type;

if (options.env === SHARE_ENV)
throw new WorkerError(errors.NO_SHARE_ENV);

if (options.eval) {
if (type === 'module')
throw new WorkerError(errors.ES_MODULE, 'eval');
Expand Down Expand Up @@ -125,6 +137,7 @@ class Worker extends EventEmitter {
options.workerData,
Boolean(options.stdin),
Boolean(options.eval),
options.env || process.env,
options.bootstrap || env.WORKER_BOOTSTRAP
])
});
Expand Down
5 changes: 5 additions & 0 deletions lib/internal/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ const errors = {
'Invalid port number (%s).'
],

NO_SHARE_ENV: [
'ERR_SHARE_ENV_NOT_SUPPORTED',
'SHARE_ENV is not supported on this backend.'
],

// High Level Worker Errors
BLACKLIST: ['ERR_WORKER_BLACKLIST', 'Cannot bind blacklisted event: "%s".'],
FATAL_ERROR: ['ERR_WORKER_FATAL_ERROR', 'Fatal exception.'],
Expand Down
1 change: 1 addition & 0 deletions lib/process/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ exports.MessagePort = MessagePortBase;
exports.MessageChannel = MessageChannel;
exports.Worker = Worker;
exports.moveMessagePortToContext = null;
exports.SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');
exports.importScripts = null;

exports.backend = 'child_process';
Expand Down
1 change: 1 addition & 0 deletions lib/process/thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ exports.MessagePort = MessagePortBase;
exports.MessageChannel = MessageChannel;
exports.Worker = Worker;
exports.moveMessagePortToContext = null;
exports.SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');
exports.importScripts = null;

exports.backend = 'child_process';
Expand Down
15 changes: 14 additions & 1 deletion lib/process/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ const {

const children = new Set();

const SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');

let uid = 1;
let exitBound = false;
let bundled = null;
Expand All @@ -76,6 +78,13 @@ class Worker extends EventEmitter {
if (typeof options !== 'object')
throw new ArgError('options', options, 'object');

if (options.env != null
&& typeof options.env !== 'object'
&& options.env !== SHARE_ENV) {
throw new ArgError('env', options.env,
['object', 'worker_threads.SHARE_ENV']);
}

if (options.execArgv && !Array.isArray(options.execArgv))
throw new ArgError('execArgv', options.execArgv, 'Array');

Expand Down Expand Up @@ -109,6 +118,9 @@ class Worker extends EventEmitter {
const bin = process.execPath || process.argv[0];
const args = [];

if (options.env === SHARE_ENV)
throw new WorkerError(errors.NO_SHARE_ENV);

// Validate filename.
if (!options.eval) {
if (!isAbsolute(file)
Expand Down Expand Up @@ -229,9 +241,10 @@ class Worker extends EventEmitter {
}

// Setup options.
const env = options.env || process.env;
const opt = {
stdio: ['pipe', 'pipe', 'pipe'],
env: Object.assign(Object.create(null), process.env, {
env: Object.assign(Object.create(null), env, {
BTHREADS_WORKER_ID: this.threadId.toString(10),
BTHREADS_WORKER_DATA: encoding.stringify(options.workerData),
BTHREADS_WORKER_STDIN: options.stdin ? '1' : '0',
Expand Down
1 change: 1 addition & 0 deletions lib/threads/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ exports.MessagePort = threads.MessagePort;
exports.MessageChannel = threads.MessageChannel;
exports.Worker = threads.Worker;
exports.moveMessagePortToContext = threads.moveMessagePortToContext || null;
exports.SHARE_ENV = threads.SHARE_ENV || null;
exports.importScripts = null;

exports.backend = 'worker_threads';
Expand Down

0 comments on commit 66f91af

Please sign in to comment.