Skip to content
This repository has been archived by the owner on Aug 31, 2018. It is now read-only.

worker: initial implementation #110

Merged
merged 1 commit into from
Oct 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,4 @@ globals:
LTTNG_NET_SERVER_CONNECTION: false
LTTNG_NET_STREAM_END: false
internalBinding: false
isMainThread: false
5 changes: 5 additions & 0 deletions lib/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@

'use strict';

if (!isMainThread) {
const errors = require('internal/errors');
throw new errors.TypeError('ERR_WORKER_DOMAIN');
}

// WARNING: THIS MODULE IS PENDING DEPRECATION.
//
// No new pull requests targeting this module will be accepted
Expand Down
49 changes: 30 additions & 19 deletions lib/internal/bootstrap_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

(function(process) {
let internalBinding;
let isMainThread;

function startup() {
const EventEmitter = NativeModule.require('events');
Expand All @@ -24,6 +25,8 @@
internalBinding = process._internalBinding;
delete process._internalBinding;

isMainThread = internalBinding('worker').threadId === 0;

// do this good and early, since it handles errors.
setupProcessFatal();

Expand Down Expand Up @@ -69,7 +72,7 @@

// Do not initialize channel in debugger agent, it deletes env variable
// and the main thread won't see it.
if (process.argv[1] !== '--debug-agent')
if (process.argv[1] !== '--debug-agent' && isMainThread)
_process.setupChannel();

_process.setupRawDebug();
Expand Down Expand Up @@ -110,8 +113,11 @@
// are running from a script and running the REPL - but there are a few
// others like the debugger or running --eval arguments. Here we decide
// which mode we run in.

if (NativeModule.exists('_third_party_main')) {
if (internalBinding('worker').getEnvMessagePort() !== undefined) {
// This means we are in a Worker context, and any script execution
// will be directed by the worker module.
NativeModule.require('internal/worker').setupChild(evalScript);
} else if (NativeModule.exists('_third_party_main')) {
// To allow people to extend Node in different ways, this hook allows
// one to drop a file lib/_third_party_main.js into the build
// directory which will be executed instead of Node's normal loading.
Expand Down Expand Up @@ -279,18 +285,20 @@
}, `'${name}' is deprecated, use 'global'`, 'DEP0016');
}

Object.defineProperties(global, {
GLOBAL: {
configurable: true,
get: makeGetter('GLOBAL'),
set: makeSetter('GLOBAL')
},
root: {
configurable: true,
get: makeGetter('root'),
set: makeSetter('root')
}
});
if (isMainThread) {
Object.defineProperties(global, {
GLOBAL: {
configurable: true,
get: makeGetter('GLOBAL'),
set: makeSetter('GLOBAL')
},
root: {
configurable: true,
get: makeGetter('root'),
set: makeSetter('root')
}
});
}

global.Buffer = NativeModule.require('buffer').Buffer;
process.domain = null;
Expand Down Expand Up @@ -446,15 +454,14 @@
return `process.binding('inspector').callAndPauseOnStart(${fn}, {})`;
}

function evalScript(name) {
function evalScript(name, body = wrapForBreakOnFirstLine(process._eval)) {
const Module = NativeModule.require('module');
const path = NativeModule.require('path');
const cwd = tryGetCwd(path);

const module = new Module(name);
module.filename = path.join(cwd, name);
module.paths = Module._nodeModulePaths(cwd);
const body = wrapForBreakOnFirstLine(process._eval);
const script = `global.__filename = ${JSON.stringify(name)};\n` +
'global.exports = exports;\n' +
'global.module = module;\n' +
Expand Down Expand Up @@ -578,7 +585,7 @@
};

NativeModule.wrapper = [
'(function (exports, require, module, internalBinding) {',
'(function (exports, require, module, internalBinding, isMainThread) {',
'\n});'
];

Expand All @@ -594,7 +601,11 @@
lineOffset: 0,
displayErrors: true
});
fn(this.exports, NativeModule.require, this, internalBinding);
fn(this.exports,
NativeModule.require,
this,
internalBinding,
isMainThread);

this.loaded = true;
} finally {
Expand Down
6 changes: 6 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ E('ERR_VALID_PERFORMANCE_ENTRY_TYPE',
E('ERR_VALUE_OUT_OF_RANGE', (start, end, value) => {
return `The value of "${start}" must be ${end}. Received "${value}"`;
});
E('ERR_WORKER_DOMAIN', 'Domains are not available inside worker threads');
E('ERR_WORKER_NEED_ABSOLUTE_PATH',
'The worker script filename must be an absolute path. Received "%s"');
E('ERR_WORKER_OUT_OF_MEMORY', 'The worker script ran out of memory');
E('ERR_WORKER_UNSERIALIZABLE_ERROR',
'Serializing an uncaught exception failed');
E('ERR_ZLIB_BINDING_CLOSED', 'zlib binding closed');

function invalidArgType(name, expected, actual) {
Expand Down
3 changes: 3 additions & 0 deletions lib/internal/process/stdio.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function setupStdio() {

function getStdout() {
if (stdout) return stdout;
if (!isMainThread) return null;
stdout = createWritableStdioStream(1);
stdout.destroySoon = stdout.destroy;
stdout._destroy = function(er, cb) {
Expand All @@ -26,6 +27,7 @@ function setupStdio() {

function getStderr() {
if (stderr) return stderr;
if (!isMainThread) return null;
stderr = createWritableStdioStream(2);
stderr.destroySoon = stderr.destroy;
stderr._destroy = function(er, cb) {
Expand All @@ -41,6 +43,7 @@ function setupStdio() {

function getStdin() {
if (stdin) return stdin;
if (!isMainThread) return null;

const tty_wrap = process.binding('tty_wrap');
const fd = 0;
Expand Down
Loading