@atlaspack/workers 2.12.1-canary.3354
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/index.d.ts +23 -0
- package/lib/Handle.js +45 -0
- package/lib/Worker.js +188 -0
- package/lib/WorkerFarm.js +563 -0
- package/lib/backend.js +34 -0
- package/lib/bus.js +31 -0
- package/lib/child.js +294 -0
- package/lib/childState.js +14 -0
- package/lib/core-worker.browser.js +4 -0
- package/lib/core-worker.js +4 -0
- package/lib/cpuCount.js +79 -0
- package/lib/index.js +75 -0
- package/lib/process/ProcessChild.js +58 -0
- package/lib/process/ProcessWorker.js +83 -0
- package/lib/threads/ThreadsChild.js +49 -0
- package/lib/threads/ThreadsWorker.js +61 -0
- package/lib/types.js +1 -0
- package/lib/web/WebChild.js +44 -0
- package/lib/web/WebWorker.js +85 -0
- package/package.json +36 -0
- package/src/Handle.js +48 -0
- package/src/Worker.js +227 -0
- package/src/WorkerFarm.js +707 -0
- package/src/backend.js +33 -0
- package/src/bus.js +26 -0
- package/src/child.js +322 -0
- package/src/childState.js +10 -0
- package/src/core-worker.browser.js +3 -0
- package/src/core-worker.js +2 -0
- package/src/cpuCount.js +75 -0
- package/src/index.js +43 -0
- package/src/process/ProcessChild.js +56 -0
- package/src/process/ProcessWorker.js +91 -0
- package/src/threads/ThreadsChild.js +42 -0
- package/src/threads/ThreadsWorker.js +66 -0
- package/src/types.js +68 -0
- package/src/web/WebChild.js +53 -0
- package/src/web/WebWorker.js +88 -0
- package/test/cpuCount.test.js +19 -0
- package/test/integration/workerfarm/console.js +15 -0
- package/test/integration/workerfarm/echo.js +5 -0
- package/test/integration/workerfarm/ipc-pid.js +18 -0
- package/test/integration/workerfarm/ipc.js +10 -0
- package/test/integration/workerfarm/logging.js +19 -0
- package/test/integration/workerfarm/master-process-id.js +3 -0
- package/test/integration/workerfarm/master-sum.js +3 -0
- package/test/integration/workerfarm/ping.js +5 -0
- package/test/integration/workerfarm/resolve-shared-reference.js +5 -0
- package/test/integration/workerfarm/reverse-handle.js +5 -0
- package/test/integration/workerfarm/shared-reference.js +6 -0
- package/test/workerfarm.js +362 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _worker_threads() {
|
|
8
|
+
const data = require("worker_threads");
|
|
9
|
+
_worker_threads = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
function _path() {
|
|
15
|
+
const data = _interopRequireDefault(require("path"));
|
|
16
|
+
_path = function () {
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
function _core() {
|
|
22
|
+
const data = require("@atlaspack/core");
|
|
23
|
+
_core = function () {
|
|
24
|
+
return data;
|
|
25
|
+
};
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
29
|
+
const WORKER_PATH = _path().default.join(__dirname, 'ThreadsChild.js');
|
|
30
|
+
class ThreadsWorker {
|
|
31
|
+
constructor(execArgv, onMessage, onError, onExit) {
|
|
32
|
+
this.execArgv = execArgv;
|
|
33
|
+
this.onMessage = onMessage;
|
|
34
|
+
this.onError = onError;
|
|
35
|
+
this.onExit = onExit;
|
|
36
|
+
}
|
|
37
|
+
start() {
|
|
38
|
+
this.worker = new (_worker_threads().Worker)(WORKER_PATH, {
|
|
39
|
+
execArgv: this.execArgv,
|
|
40
|
+
env: process.env
|
|
41
|
+
});
|
|
42
|
+
this.worker.on('message', data => this.handleMessage(data));
|
|
43
|
+
this.worker.on('error', this.onError);
|
|
44
|
+
this.worker.on('exit', this.onExit);
|
|
45
|
+
return new Promise(resolve => {
|
|
46
|
+
this.worker.on('online', resolve);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
stop() {
|
|
50
|
+
// In node 12, this returns a promise, but previously it accepted a callback
|
|
51
|
+
// TODO: Pass a callback in earlier versions of Node
|
|
52
|
+
return Promise.resolve(this.worker.terminate());
|
|
53
|
+
}
|
|
54
|
+
handleMessage(data) {
|
|
55
|
+
this.onMessage((0, _core().restoreDeserializedObject)(data));
|
|
56
|
+
}
|
|
57
|
+
send(data) {
|
|
58
|
+
this.worker.postMessage((0, _core().prepareForSerialization)(data));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.default = ThreadsWorker;
|
package/lib/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _childState = require("../childState");
|
|
8
|
+
var _child = require("../child");
|
|
9
|
+
function _core() {
|
|
10
|
+
const data = require("@atlaspack/core");
|
|
11
|
+
_core = function () {
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
/* eslint-env worker*/
|
|
17
|
+
class WebChild {
|
|
18
|
+
constructor(onMessage, onExit) {
|
|
19
|
+
if (!(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)) {
|
|
20
|
+
throw new Error('Only create WebChild instances in a worker!');
|
|
21
|
+
}
|
|
22
|
+
this.onMessage = onMessage;
|
|
23
|
+
this.onExit = onExit;
|
|
24
|
+
self.addEventListener('message', ({
|
|
25
|
+
data
|
|
26
|
+
}) => {
|
|
27
|
+
if (data === 'stop') {
|
|
28
|
+
this.onExit(0);
|
|
29
|
+
self.postMessage('stopped');
|
|
30
|
+
}
|
|
31
|
+
// $FlowFixMe assume WorkerMessage as data
|
|
32
|
+
this.handleMessage(data);
|
|
33
|
+
});
|
|
34
|
+
self.postMessage('online');
|
|
35
|
+
}
|
|
36
|
+
handleMessage(data) {
|
|
37
|
+
this.onMessage((0, _core().restoreDeserializedObject)(data));
|
|
38
|
+
}
|
|
39
|
+
send(data) {
|
|
40
|
+
self.postMessage((0, _core().prepareForSerialization)(data));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.default = WebChild;
|
|
44
|
+
(0, _childState.setChild)(new _child.Child(WebChild));
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _core() {
|
|
8
|
+
const data = require("@atlaspack/core");
|
|
9
|
+
_core = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
function _utils() {
|
|
15
|
+
const data = require("@atlaspack/utils");
|
|
16
|
+
_utils = function () {
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
let id = 0;
|
|
22
|
+
class WebWorker {
|
|
23
|
+
constructor(execArgv, onMessage, onError, onExit) {
|
|
24
|
+
this.execArgv = execArgv;
|
|
25
|
+
this.onMessage = onMessage;
|
|
26
|
+
this.onError = onError;
|
|
27
|
+
this.onExit = onExit;
|
|
28
|
+
}
|
|
29
|
+
start() {
|
|
30
|
+
// $FlowFixMe[incompatible-call]
|
|
31
|
+
this.worker = new Worker(new URL('./WebChild.js', import.meta.url), {
|
|
32
|
+
name: `Atlaspack Worker ${id++}`,
|
|
33
|
+
type: 'module'
|
|
34
|
+
});
|
|
35
|
+
let {
|
|
36
|
+
deferred,
|
|
37
|
+
promise
|
|
38
|
+
} = (0, _utils().makeDeferredWithPromise)();
|
|
39
|
+
this.worker.onmessage = ({
|
|
40
|
+
data
|
|
41
|
+
}) => {
|
|
42
|
+
if (data === 'online') {
|
|
43
|
+
deferred.resolve();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// $FlowFixMe assume WorkerMessage as data
|
|
48
|
+
this.handleMessage(data);
|
|
49
|
+
};
|
|
50
|
+
this.worker.onerror = this.onError;
|
|
51
|
+
// Web workers can't crash or intentionally stop on their own, apart from stop() below
|
|
52
|
+
// this.worker.on('exit', this.onExit);
|
|
53
|
+
|
|
54
|
+
return promise;
|
|
55
|
+
}
|
|
56
|
+
stop() {
|
|
57
|
+
if (!this.stopping) {
|
|
58
|
+
this.stopping = (async () => {
|
|
59
|
+
this.worker.postMessage('stop');
|
|
60
|
+
let {
|
|
61
|
+
deferred,
|
|
62
|
+
promise
|
|
63
|
+
} = (0, _utils().makeDeferredWithPromise)();
|
|
64
|
+
this.worker.addEventListener('message', ({
|
|
65
|
+
data
|
|
66
|
+
}) => {
|
|
67
|
+
if (data === 'stopped') {
|
|
68
|
+
deferred.resolve();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
await promise;
|
|
72
|
+
this.worker.terminate();
|
|
73
|
+
this.onExit(0);
|
|
74
|
+
})();
|
|
75
|
+
}
|
|
76
|
+
return this.stopping;
|
|
77
|
+
}
|
|
78
|
+
handleMessage(data) {
|
|
79
|
+
this.onMessage((0, _core().restoreDeserializedObject)(data));
|
|
80
|
+
}
|
|
81
|
+
send(data) {
|
|
82
|
+
this.worker.postMessage((0, _core().prepareForSerialization)(data));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.default = WebWorker;
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaspack/workers",
|
|
3
|
+
"version": "2.12.1-canary.3354+7bb54d46a",
|
|
4
|
+
"description": "Blazing fast, zero configuration web application bundler",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
12
|
+
},
|
|
13
|
+
"main": "lib/index.js",
|
|
14
|
+
"source": "src/index.js",
|
|
15
|
+
"types": "index.d.ts",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">= 16.0.0"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@atlaspack/diagnostic": "2.12.1-canary.3354+7bb54d46a",
|
|
21
|
+
"@atlaspack/logger": "2.12.1-canary.3354+7bb54d46a",
|
|
22
|
+
"@atlaspack/profiler": "2.12.1-canary.3354+7bb54d46a",
|
|
23
|
+
"@atlaspack/types-internal": "2.12.1-canary.3354+7bb54d46a",
|
|
24
|
+
"@atlaspack/utils": "2.12.1-canary.3354+7bb54d46a",
|
|
25
|
+
"nullthrows": "^1.1.1"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@atlaspack/core": "2.12.1-canary.3354+7bb54d46a"
|
|
29
|
+
},
|
|
30
|
+
"browser": {
|
|
31
|
+
"./src/process/ProcessWorker.js": false,
|
|
32
|
+
"./src/threads/ThreadsWorker.js": false,
|
|
33
|
+
"./src/core-worker.js": "./src/core-worker.browser.js"
|
|
34
|
+
},
|
|
35
|
+
"gitHead": "7bb54d46a00c5ba9cdbc2ee426dcbe82c8d79a3e"
|
|
36
|
+
}
|
package/src/Handle.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
import {registerSerializableClass} from '@atlaspack/core';
|
|
3
|
+
// $FlowFixMe
|
|
4
|
+
import packageJson from '../package.json';
|
|
5
|
+
|
|
6
|
+
let HANDLE_ID = 0;
|
|
7
|
+
// $FlowFixMe
|
|
8
|
+
export type HandleFunction = (...args: Array<any>) => any;
|
|
9
|
+
|
|
10
|
+
type HandleOpts = {|
|
|
11
|
+
fn?: HandleFunction,
|
|
12
|
+
childId?: ?number,
|
|
13
|
+
id?: number,
|
|
14
|
+
|};
|
|
15
|
+
|
|
16
|
+
const handleById: Map<number, Handle> = new Map();
|
|
17
|
+
|
|
18
|
+
export default class Handle {
|
|
19
|
+
id: number;
|
|
20
|
+
childId: ?number;
|
|
21
|
+
fn: ?HandleFunction;
|
|
22
|
+
|
|
23
|
+
constructor(opts: HandleOpts) {
|
|
24
|
+
this.id = opts.id ?? ++HANDLE_ID;
|
|
25
|
+
this.fn = opts.fn;
|
|
26
|
+
this.childId = opts.childId;
|
|
27
|
+
handleById.set(this.id, this);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
dispose() {
|
|
31
|
+
handleById.delete(this.id);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
serialize(): {|childId: ?number, id: number|} {
|
|
35
|
+
return {
|
|
36
|
+
id: this.id,
|
|
37
|
+
childId: this.childId,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static deserialize(opts: HandleOpts): Handle {
|
|
42
|
+
return new Handle(opts);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Register the Handle as a serializable class so that it will properly be deserialized
|
|
47
|
+
// by anything that uses WorkerFarm.
|
|
48
|
+
registerSerializableClass(`${packageJson.version}:Handle`, Handle);
|
package/src/Worker.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import type {FilePath} from '@atlaspack/types-internal';
|
|
4
|
+
import type {BackendType, WorkerImpl, WorkerMessage} from './types';
|
|
5
|
+
import type {SharedReference} from './WorkerFarm';
|
|
6
|
+
|
|
7
|
+
import nullthrows from 'nullthrows';
|
|
8
|
+
import EventEmitter from 'events';
|
|
9
|
+
import ThrowableDiagnostic from '@atlaspack/diagnostic';
|
|
10
|
+
import {getWorkerBackend} from './backend';
|
|
11
|
+
|
|
12
|
+
export type WorkerCall = {|
|
|
13
|
+
method?: string,
|
|
14
|
+
handle?: number,
|
|
15
|
+
args: $ReadOnlyArray<any>,
|
|
16
|
+
retries: number,
|
|
17
|
+
skipReadyCheck?: boolean,
|
|
18
|
+
resolve: (result: Promise<any> | any) => void,
|
|
19
|
+
reject: (error: any) => void,
|
|
20
|
+
|};
|
|
21
|
+
|
|
22
|
+
type WorkerOpts = {|
|
|
23
|
+
forcedKillTime: number,
|
|
24
|
+
backend: BackendType,
|
|
25
|
+
shouldPatchConsole?: boolean,
|
|
26
|
+
shouldTrace?: boolean,
|
|
27
|
+
sharedReferences: $ReadOnlyMap<SharedReference, mixed>,
|
|
28
|
+
|};
|
|
29
|
+
|
|
30
|
+
let WORKER_ID = 0;
|
|
31
|
+
export default class Worker extends EventEmitter {
|
|
32
|
+
+options: WorkerOpts;
|
|
33
|
+
worker: WorkerImpl;
|
|
34
|
+
id: number = WORKER_ID++;
|
|
35
|
+
sentSharedReferences: Set<SharedReference> = new Set();
|
|
36
|
+
|
|
37
|
+
calls: Map<number, WorkerCall> = new Map();
|
|
38
|
+
exitCode: ?number = null;
|
|
39
|
+
callId: number = 0;
|
|
40
|
+
|
|
41
|
+
ready: boolean = false;
|
|
42
|
+
stopped: boolean = false;
|
|
43
|
+
isStopping: boolean = false;
|
|
44
|
+
|
|
45
|
+
constructor(options: WorkerOpts) {
|
|
46
|
+
super();
|
|
47
|
+
this.options = options;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async fork(forkModule: FilePath) {
|
|
51
|
+
let filteredArgs = [];
|
|
52
|
+
if (process.execArgv) {
|
|
53
|
+
filteredArgs = process.execArgv.filter(
|
|
54
|
+
v =>
|
|
55
|
+
!/^--(debug|inspect|no-opt|max-old-space-size=|max-semi-space-size=|expose-gc)/.test(
|
|
56
|
+
v,
|
|
57
|
+
),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < filteredArgs.length; i++) {
|
|
61
|
+
let arg = filteredArgs[i];
|
|
62
|
+
let isArgWithParam =
|
|
63
|
+
((arg === '-r' || arg === '--require') &&
|
|
64
|
+
filteredArgs[i + 1] === '@atlaspack/register') ||
|
|
65
|
+
arg === '--title';
|
|
66
|
+
if (isArgWithParam) {
|
|
67
|
+
filteredArgs.splice(i, 2);
|
|
68
|
+
i--;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Workaround for https://github.com/nodejs/node/issues/29117
|
|
74
|
+
if (process.env.NODE_OPTIONS) {
|
|
75
|
+
// arg parsing logic adapted from https://stackoverflow.com/a/46946420/2352201
|
|
76
|
+
let opts = [''];
|
|
77
|
+
let quote = false;
|
|
78
|
+
for (let c of nullthrows(process.env.NODE_OPTIONS.match(/.|^$/g))) {
|
|
79
|
+
if (c === '"') {
|
|
80
|
+
quote = !quote;
|
|
81
|
+
} else if (!quote && c === ' ') {
|
|
82
|
+
opts.push('');
|
|
83
|
+
} else {
|
|
84
|
+
opts[opts.length - 1] += c.replace(/\\(.)/, '$1');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (let i = 0; i < opts.length; i++) {
|
|
89
|
+
let opt = opts[i];
|
|
90
|
+
if (opt === '-r' || opt === '--require') {
|
|
91
|
+
filteredArgs.push(opt, opts[i + 1]);
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let onMessage = data => this.receive(data);
|
|
98
|
+
let onExit = code => {
|
|
99
|
+
this.exitCode = code;
|
|
100
|
+
this.emit('exit', code);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
let onError = err => {
|
|
104
|
+
this.emit('error', err);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
let WorkerBackend = getWorkerBackend(this.options.backend);
|
|
108
|
+
this.worker = new WorkerBackend(filteredArgs, onMessage, onError, onExit);
|
|
109
|
+
await this.worker.start();
|
|
110
|
+
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
this.call({
|
|
113
|
+
method: 'childInit',
|
|
114
|
+
args: [
|
|
115
|
+
forkModule,
|
|
116
|
+
{
|
|
117
|
+
shouldPatchConsole: !!this.options.shouldPatchConsole,
|
|
118
|
+
shouldTrace: !!this.options.shouldTrace,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
retries: 0,
|
|
122
|
+
skipReadyCheck: true,
|
|
123
|
+
resolve,
|
|
124
|
+
reject,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
let sharedRefs = this.options.sharedReferences;
|
|
129
|
+
let refsShared = new Set();
|
|
130
|
+
// in case more refs are created while initial refs are sending
|
|
131
|
+
while (refsShared.size < sharedRefs.size) {
|
|
132
|
+
await Promise.all(
|
|
133
|
+
[...sharedRefs]
|
|
134
|
+
.filter(([ref]) => !refsShared.has(ref))
|
|
135
|
+
.map(async ([ref, value]) => {
|
|
136
|
+
await this.sendSharedReference(ref, value);
|
|
137
|
+
refsShared.add(ref);
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this.ready = true;
|
|
143
|
+
this.emit('ready');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
sendSharedReference(ref: SharedReference, value: mixed): Promise<any> {
|
|
147
|
+
this.sentSharedReferences.add(ref);
|
|
148
|
+
return new Promise((resolve, reject) => {
|
|
149
|
+
this.call({
|
|
150
|
+
method: 'createSharedReference',
|
|
151
|
+
args: [ref, value],
|
|
152
|
+
resolve,
|
|
153
|
+
reject,
|
|
154
|
+
retries: 0,
|
|
155
|
+
skipReadyCheck: true,
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
send(data: WorkerMessage): void {
|
|
161
|
+
this.worker.send(data);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
call(call: WorkerCall): void {
|
|
165
|
+
if (this.stopped || this.isStopping) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let idx = this.callId++;
|
|
170
|
+
this.calls.set(idx, call);
|
|
171
|
+
|
|
172
|
+
let msg = {
|
|
173
|
+
type: 'request',
|
|
174
|
+
idx: idx,
|
|
175
|
+
child: this.id,
|
|
176
|
+
handle: call.handle,
|
|
177
|
+
method: call.method,
|
|
178
|
+
args: call.args,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
if (this.ready || call.skipReadyCheck === true) {
|
|
182
|
+
this.send(msg);
|
|
183
|
+
} else {
|
|
184
|
+
this.once('ready', () => this.send(msg));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
receive(message: WorkerMessage): void {
|
|
189
|
+
if (this.stopped || this.isStopping) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (message.type === 'request') {
|
|
194
|
+
this.emit('request', message);
|
|
195
|
+
} else if (message.type === 'response') {
|
|
196
|
+
let idx = message.idx;
|
|
197
|
+
if (idx == null) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
let call = this.calls.get(idx);
|
|
202
|
+
if (!call) {
|
|
203
|
+
// Return for unknown calls, these might accur if a third party process uses workers
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (message.contentType === 'error') {
|
|
208
|
+
call.reject(new ThrowableDiagnostic({diagnostic: message.content}));
|
|
209
|
+
} else {
|
|
210
|
+
call.resolve(message.content);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
this.calls.delete(idx);
|
|
214
|
+
this.emit('response', message);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async stop() {
|
|
219
|
+
if (!this.stopped) {
|
|
220
|
+
this.stopped = true;
|
|
221
|
+
|
|
222
|
+
if (this.worker) {
|
|
223
|
+
await this.worker.stop();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|