@atlaspack/workers 2.14.21-typescript-e99c742e9.0 → 2.14.21-typescript-bc4459c37.0
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/lib/Handle.d.ts +19 -0
- package/lib/Handle.js +42 -0
- package/lib/Worker.d.ts +40 -0
- package/lib/Worker.js +194 -0
- package/lib/WorkerFarm.d.ts +93 -0
- package/lib/WorkerFarm.js +563 -0
- package/lib/backend.d.ts +4 -0
- package/lib/backend.js +38 -0
- package/lib/bus.d.ts +6 -0
- package/lib/bus.js +31 -0
- package/lib/child.d.ts +43 -0
- package/lib/child.js +291 -0
- package/lib/childState.d.ts +3 -0
- package/lib/childState.js +14 -0
- package/lib/cpuCount.d.ts +2 -0
- package/lib/cpuCount.js +83 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +75 -0
- package/lib/process/ProcessChild.d.ts +9 -0
- package/lib/process/ProcessChild.js +63 -0
- package/lib/process/ProcessWorker.d.ts +16 -0
- package/lib/process/ProcessWorker.js +90 -0
- package/lib/threads/ThreadsChild.d.ts +8 -0
- package/lib/threads/ThreadsChild.js +52 -0
- package/lib/threads/ThreadsWorker.d.ts +15 -0
- package/lib/threads/ThreadsWorker.js +69 -0
- package/lib/types.d.ts +52 -0
- package/lib/types.js +1 -0
- package/lib/web/WebChild.d.ts +8 -0
- package/lib/web/WebChild.js +49 -0
- package/lib/web/WebWorker.d.ts +15 -0
- package/lib/web/WebWorker.js +101 -0
- package/package.json +8 -8
package/lib/Handle.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type HandleFunction = (...args: Array<any>) => any;
|
|
2
|
+
type HandleOpts = {
|
|
3
|
+
fn?: HandleFunction;
|
|
4
|
+
childId?: number | null | undefined;
|
|
5
|
+
id?: number;
|
|
6
|
+
};
|
|
7
|
+
export default class Handle {
|
|
8
|
+
id: number;
|
|
9
|
+
childId: number | null | undefined;
|
|
10
|
+
fn: HandleFunction | null | undefined;
|
|
11
|
+
constructor(opts: HandleOpts);
|
|
12
|
+
dispose(): void;
|
|
13
|
+
serialize(): {
|
|
14
|
+
childId: number | null | undefined;
|
|
15
|
+
id: number;
|
|
16
|
+
};
|
|
17
|
+
static deserialize(opts: HandleOpts): Handle;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
package/lib/Handle.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _buildCache() {
|
|
8
|
+
const data = require("@atlaspack/build-cache");
|
|
9
|
+
_buildCache = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
var _package = _interopRequireDefault(require("../package.json"));
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
let HANDLE_ID = 0;
|
|
17
|
+
const handleById = new Map();
|
|
18
|
+
class Handle {
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
this.id = opts.id ?? ++HANDLE_ID;
|
|
21
|
+
this.fn = opts.fn;
|
|
22
|
+
this.childId = opts.childId;
|
|
23
|
+
handleById.set(this.id, this);
|
|
24
|
+
}
|
|
25
|
+
dispose() {
|
|
26
|
+
handleById.delete(this.id);
|
|
27
|
+
}
|
|
28
|
+
serialize() {
|
|
29
|
+
return {
|
|
30
|
+
id: this.id,
|
|
31
|
+
childId: this.childId
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
static deserialize(opts) {
|
|
35
|
+
return new Handle(opts);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Register the Handle as a serializable class so that it will properly be deserialized
|
|
40
|
+
// by anything that uses WorkerFarm.
|
|
41
|
+
exports.default = Handle;
|
|
42
|
+
(0, _buildCache().registerSerializableClass)(`${_package.default.version}:Handle`, Handle);
|
package/lib/Worker.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { FilePath } from '@atlaspack/types-internal';
|
|
2
|
+
import type { BackendType, WorkerImpl, WorkerMessage } from './types';
|
|
3
|
+
import type { SharedReference } from './WorkerFarm';
|
|
4
|
+
import EventEmitter from 'events';
|
|
5
|
+
export type WorkerCall = {
|
|
6
|
+
method?: string;
|
|
7
|
+
handle?: number;
|
|
8
|
+
args: ReadonlyArray<any>;
|
|
9
|
+
retries: number;
|
|
10
|
+
skipReadyCheck?: boolean;
|
|
11
|
+
resolve: (result: Promise<any> | any) => void;
|
|
12
|
+
reject: (error?: any) => void;
|
|
13
|
+
};
|
|
14
|
+
type WorkerOpts = {
|
|
15
|
+
forcedKillTime: number;
|
|
16
|
+
backend: BackendType;
|
|
17
|
+
shouldPatchConsole?: boolean;
|
|
18
|
+
shouldTrace?: boolean;
|
|
19
|
+
sharedReferences: ReadonlyMap<SharedReference, unknown>;
|
|
20
|
+
};
|
|
21
|
+
export default class Worker extends EventEmitter {
|
|
22
|
+
readonly options: WorkerOpts;
|
|
23
|
+
worker: WorkerImpl;
|
|
24
|
+
id: number;
|
|
25
|
+
sentSharedReferences: Set<SharedReference>;
|
|
26
|
+
calls: Map<number, WorkerCall>;
|
|
27
|
+
exitCode: number | null | undefined;
|
|
28
|
+
callId: number;
|
|
29
|
+
ready: boolean;
|
|
30
|
+
stopped: boolean;
|
|
31
|
+
isStopping: boolean;
|
|
32
|
+
constructor(options: WorkerOpts);
|
|
33
|
+
fork(forkModule: FilePath): Promise<void>;
|
|
34
|
+
sendSharedReference(ref: SharedReference, value: unknown): Promise<any>;
|
|
35
|
+
send(data: WorkerMessage): void;
|
|
36
|
+
call(call: WorkerCall): void;
|
|
37
|
+
receive(message: WorkerMessage): void;
|
|
38
|
+
stop(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
package/lib/Worker.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _nullthrows() {
|
|
8
|
+
const data = _interopRequireDefault(require("nullthrows"));
|
|
9
|
+
_nullthrows = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
function _events() {
|
|
15
|
+
const data = _interopRequireDefault(require("events"));
|
|
16
|
+
_events = function () {
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
function _diagnostic() {
|
|
22
|
+
const data = _interopRequireDefault(require("@atlaspack/diagnostic"));
|
|
23
|
+
_diagnostic = function () {
|
|
24
|
+
return data;
|
|
25
|
+
};
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
var _backend = require("./backend");
|
|
29
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
30
|
+
let WORKER_ID = 0;
|
|
31
|
+
class Worker extends _events().default {
|
|
32
|
+
// @ts-expect-error TS2564
|
|
33
|
+
|
|
34
|
+
id = WORKER_ID++;
|
|
35
|
+
sentSharedReferences = new Set();
|
|
36
|
+
calls = new Map();
|
|
37
|
+
exitCode = null;
|
|
38
|
+
callId = 0;
|
|
39
|
+
ready = false;
|
|
40
|
+
stopped = false;
|
|
41
|
+
isStopping = false;
|
|
42
|
+
constructor(options) {
|
|
43
|
+
super();
|
|
44
|
+
this.options = options;
|
|
45
|
+
}
|
|
46
|
+
async fork(forkModule) {
|
|
47
|
+
let filteredArgs = [];
|
|
48
|
+
if (process.execArgv) {
|
|
49
|
+
filteredArgs = process.execArgv.filter(v => !/^--(debug|inspect|no-opt|max-old-space-size=|max-semi-space-size=|expose-gc)/.test(v));
|
|
50
|
+
for (let i = 0; i < filteredArgs.length; i++) {
|
|
51
|
+
let arg = filteredArgs[i];
|
|
52
|
+
let isArgWithParam = (arg === '-r' || arg === '--require') && filteredArgs[i + 1] === '@atlaspack/register' || arg === '--title';
|
|
53
|
+
if (isArgWithParam) {
|
|
54
|
+
filteredArgs.splice(i, 2);
|
|
55
|
+
i--;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Workaround for https://github.com/nodejs/node/issues/29117
|
|
61
|
+
if (process.env.NODE_OPTIONS) {
|
|
62
|
+
// arg parsing logic adapted from https://stackoverflow.com/a/46946420/2352201
|
|
63
|
+
let opts = [''];
|
|
64
|
+
let quote = false;
|
|
65
|
+
for (let c of (0, _nullthrows().default)(process.env.NODE_OPTIONS.match(/.|^$/g))) {
|
|
66
|
+
if (c === '"') {
|
|
67
|
+
quote = !quote;
|
|
68
|
+
} else if (!quote && c === ' ') {
|
|
69
|
+
opts.push('');
|
|
70
|
+
} else {
|
|
71
|
+
opts[opts.length - 1] += c.replace(/\\(.)/, '$1');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (let i = 0; i < opts.length; i++) {
|
|
75
|
+
let opt = opts[i];
|
|
76
|
+
if (opt === '-r' || opt === '--require') {
|
|
77
|
+
filteredArgs.push(opt, opts[i + 1]);
|
|
78
|
+
i++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
let onMessage = data => this.receive(data);
|
|
83
|
+
let onExit = code => {
|
|
84
|
+
this.exitCode = code;
|
|
85
|
+
this.emit('exit', code);
|
|
86
|
+
};
|
|
87
|
+
let onError = err => {
|
|
88
|
+
this.emit('error', err);
|
|
89
|
+
};
|
|
90
|
+
let WorkerBackend = (0, _backend.getWorkerBackend)(this.options.backend);
|
|
91
|
+
this.worker = new WorkerBackend(filteredArgs, onMessage, onError, onExit);
|
|
92
|
+
await this.worker.start();
|
|
93
|
+
await new Promise((resolve, reject) => {
|
|
94
|
+
this.call({
|
|
95
|
+
method: 'childInit',
|
|
96
|
+
args: [forkModule, {
|
|
97
|
+
shouldPatchConsole: !!this.options.shouldPatchConsole,
|
|
98
|
+
shouldTrace: !!this.options.shouldTrace
|
|
99
|
+
}],
|
|
100
|
+
retries: 0,
|
|
101
|
+
skipReadyCheck: true,
|
|
102
|
+
resolve,
|
|
103
|
+
reject
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
let sharedRefs = this.options.sharedReferences;
|
|
107
|
+
let refsShared = new Set();
|
|
108
|
+
// in case more refs are created while initial refs are sending
|
|
109
|
+
while (refsShared.size < sharedRefs.size) {
|
|
110
|
+
await Promise.all([...sharedRefs]
|
|
111
|
+
// @ts-expect-error TS2769
|
|
112
|
+
.filter(([ref]) => !refsShared.has(ref)).map(async ([ref, value]) => {
|
|
113
|
+
await this.sendSharedReference(ref, value);
|
|
114
|
+
refsShared.add(ref);
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
this.ready = true;
|
|
118
|
+
this.emit('ready');
|
|
119
|
+
}
|
|
120
|
+
sendSharedReference(ref, value) {
|
|
121
|
+
this.sentSharedReferences.add(ref);
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
this.call({
|
|
124
|
+
method: 'createSharedReference',
|
|
125
|
+
args: [ref, value],
|
|
126
|
+
resolve,
|
|
127
|
+
reject,
|
|
128
|
+
retries: 0,
|
|
129
|
+
skipReadyCheck: true
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
send(data) {
|
|
134
|
+
this.worker.send(data);
|
|
135
|
+
}
|
|
136
|
+
call(call) {
|
|
137
|
+
if (this.stopped || this.isStopping) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
let idx = this.callId++;
|
|
141
|
+
this.calls.set(idx, call);
|
|
142
|
+
let msg = {
|
|
143
|
+
type: 'request',
|
|
144
|
+
idx: idx,
|
|
145
|
+
child: this.id,
|
|
146
|
+
handle: call.handle,
|
|
147
|
+
method: call.method,
|
|
148
|
+
args: call.args
|
|
149
|
+
};
|
|
150
|
+
if (this.ready || call.skipReadyCheck === true) {
|
|
151
|
+
// @ts-expect-error TS2345
|
|
152
|
+
this.send(msg);
|
|
153
|
+
} else {
|
|
154
|
+
// @ts-expect-error TS2345
|
|
155
|
+
this.once('ready', () => this.send(msg));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
receive(message) {
|
|
159
|
+
if (this.stopped || this.isStopping) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (message.type === 'request') {
|
|
163
|
+
this.emit('request', message);
|
|
164
|
+
} else if (message.type === 'response') {
|
|
165
|
+
let idx = message.idx;
|
|
166
|
+
if (idx == null) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
let call = this.calls.get(idx);
|
|
170
|
+
if (!call) {
|
|
171
|
+
// Return for unknown calls, these might accur if a third party process uses workers
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (message.contentType === 'error') {
|
|
175
|
+
call.reject(new (_diagnostic().default)({
|
|
176
|
+
diagnostic: message.content
|
|
177
|
+
}));
|
|
178
|
+
} else {
|
|
179
|
+
call.resolve(message.content);
|
|
180
|
+
}
|
|
181
|
+
this.calls.delete(idx);
|
|
182
|
+
this.emit('response', message);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async stop() {
|
|
186
|
+
if (!this.stopped) {
|
|
187
|
+
this.stopped = true;
|
|
188
|
+
if (this.worker) {
|
|
189
|
+
await this.worker.stop();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
exports.default = Worker;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { ErrorWithCode, FilePath } from '@atlaspack/types-internal';
|
|
2
|
+
import type { CallRequest, HandleCallRequest, WorkerRequest, BackendType } from './types';
|
|
3
|
+
import type { HandleFunction } from './Handle';
|
|
4
|
+
import EventEmitter from 'events';
|
|
5
|
+
import Worker, { WorkerCall } from './Worker';
|
|
6
|
+
import Handle from './Handle';
|
|
7
|
+
import { SamplingProfiler } from '@atlaspack/profiler';
|
|
8
|
+
export type SharedReference = number;
|
|
9
|
+
export type FarmOptions = {
|
|
10
|
+
maxConcurrentWorkers: number;
|
|
11
|
+
maxConcurrentCallsPerWorker: number;
|
|
12
|
+
forcedKillTime: number;
|
|
13
|
+
useLocalWorker: boolean;
|
|
14
|
+
warmWorkers: boolean;
|
|
15
|
+
workerPath?: FilePath;
|
|
16
|
+
backend: BackendType;
|
|
17
|
+
shouldPatchConsole?: boolean;
|
|
18
|
+
shouldTrace?: boolean;
|
|
19
|
+
};
|
|
20
|
+
type WorkerModule = {
|
|
21
|
+
readonly [key: string]: (...args: Array<unknown>) => Promise<unknown>;
|
|
22
|
+
};
|
|
23
|
+
export type WorkerApi = {
|
|
24
|
+
callMaster(arg1: CallRequest, arg2?: boolean | null | undefined): Promise<unknown>;
|
|
25
|
+
createReverseHandle(fn: HandleFunction): Handle;
|
|
26
|
+
getSharedReference(ref: SharedReference): unknown;
|
|
27
|
+
resolveSharedReference(value: unknown): SharedReference | null | undefined;
|
|
28
|
+
callChild?: (childId: number, request: HandleCallRequest) => Promise<unknown>;
|
|
29
|
+
};
|
|
30
|
+
export { Handle };
|
|
31
|
+
/**
|
|
32
|
+
* workerPath should always be defined inside farmOptions
|
|
33
|
+
*/
|
|
34
|
+
export default class WorkerFarm extends EventEmitter {
|
|
35
|
+
callQueue: Array<WorkerCall>;
|
|
36
|
+
ending: boolean;
|
|
37
|
+
localWorker: WorkerModule;
|
|
38
|
+
localWorkerInit: Promise<undefined> | null | undefined;
|
|
39
|
+
options: FarmOptions;
|
|
40
|
+
run: HandleFunction;
|
|
41
|
+
warmWorkers: number;
|
|
42
|
+
readyWorkers: number;
|
|
43
|
+
workers: Map<number, Worker>;
|
|
44
|
+
handles: Map<number, Handle>;
|
|
45
|
+
sharedReferences: Map<SharedReference, unknown>;
|
|
46
|
+
sharedReferencesByValue: Map<unknown, SharedReference>;
|
|
47
|
+
serializedSharedReferences: Map<SharedReference, ArrayBuffer | null | undefined>;
|
|
48
|
+
profiler: SamplingProfiler | null | undefined;
|
|
49
|
+
constructor(farmOptions?: Partial<FarmOptions>);
|
|
50
|
+
workerApi: {
|
|
51
|
+
callChild: (childId: number, request: HandleCallRequest) => Promise<unknown>;
|
|
52
|
+
callMaster: (request: CallRequest, awaitResponse?: boolean | null | undefined) => Promise<unknown>;
|
|
53
|
+
createReverseHandle: (fn: HandleFunction) => Handle;
|
|
54
|
+
getSharedReference: (ref: SharedReference) => unknown;
|
|
55
|
+
resolveSharedReference: (value: unknown) => undefined | SharedReference;
|
|
56
|
+
runHandle: (handle: Handle, args: Array<any>) => Promise<unknown>;
|
|
57
|
+
};
|
|
58
|
+
warmupWorker(method: string, args: Array<any>): void;
|
|
59
|
+
shouldStartRemoteWorkers(): boolean;
|
|
60
|
+
createHandle(method: string, useMainThread?: boolean): HandleFunction;
|
|
61
|
+
onError(error: ErrorWithCode, worker: Worker): undefined | Promise<undefined>;
|
|
62
|
+
startChild(): void;
|
|
63
|
+
stopWorker(worker: Worker): Promise<void>;
|
|
64
|
+
processQueue(): void;
|
|
65
|
+
callWorker(worker: Worker, call: WorkerCall): Promise<void>;
|
|
66
|
+
processRequest(data: {
|
|
67
|
+
location: FilePath;
|
|
68
|
+
} & Partial<WorkerRequest>, worker?: Worker): Promise<string | null | undefined>;
|
|
69
|
+
addCall(method: string, args: Array<any>): Promise<any>;
|
|
70
|
+
end(): Promise<void>;
|
|
71
|
+
startMaxWorkers(): void;
|
|
72
|
+
shouldUseRemoteWorkers(): boolean;
|
|
73
|
+
createReverseHandle(fn: HandleFunction): Handle;
|
|
74
|
+
createSharedReference(value: unknown, isCacheable?: boolean): {
|
|
75
|
+
ref: SharedReference;
|
|
76
|
+
dispose(): Promise<unknown>;
|
|
77
|
+
};
|
|
78
|
+
getSerializedSharedReference(ref: SharedReference): ArrayBuffer;
|
|
79
|
+
startProfile(): Promise<void>;
|
|
80
|
+
endProfile(): Promise<void>;
|
|
81
|
+
callAllWorkers(method: string, args: Array<any>): Promise<void>;
|
|
82
|
+
takeHeapSnapshot(): Promise<void>;
|
|
83
|
+
static getNumWorkers(): number;
|
|
84
|
+
static isWorker(): boolean;
|
|
85
|
+
static getWorkerApi(): {
|
|
86
|
+
callMaster: (request: CallRequest, awaitResponse?: boolean | null | undefined) => Promise<unknown>;
|
|
87
|
+
createReverseHandle: (fn: (...args: Array<any>) => unknown) => Handle;
|
|
88
|
+
getSharedReference: (ref: SharedReference) => unknown;
|
|
89
|
+
resolveSharedReference: (value: unknown) => undefined | SharedReference;
|
|
90
|
+
runHandle: (handle: Handle, args: Array<any>) => Promise<unknown>;
|
|
91
|
+
};
|
|
92
|
+
static getConcurrentCallsPerWorker(defaultValue?: number): number;
|
|
93
|
+
}
|