@parcel/workers 2.0.0-nightly.144 → 2.0.0-nightly.1441
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/index.d.ts +23 -0
- package/lib/Handle.js +16 -58
- package/lib/Worker.js +95 -57
- package/lib/WorkerFarm.js +272 -192
- package/lib/backend.js +4 -6
- package/lib/bus.js +10 -11
- package/lib/child.js +140 -116
- package/lib/childState.js +1 -2
- package/lib/core-worker.browser.js +4 -0
- package/lib/core-worker.js +4 -0
- package/lib/cpuCount.js +36 -25
- package/lib/index.js +34 -30
- package/lib/process/ProcessChild.js +18 -24
- package/lib/process/ProcessWorker.js +27 -38
- package/lib/threads/ThreadsChild.js +26 -28
- package/lib/threads/ThreadsWorker.js +25 -31
- package/lib/web/WebChild.js +44 -0
- package/lib/web/WebWorker.js +85 -0
- package/package.json +19 -8
- package/src/Handle.js +10 -39
- package/src/Worker.js +92 -22
- package/src/WorkerFarm.js +267 -62
- package/src/backend.js +5 -0
- package/src/bus.js +3 -2
- package/src/child.js +95 -26
- package/src/core-worker.browser.js +3 -0
- package/src/core-worker.js +2 -0
- package/src/cpuCount.js +23 -10
- package/src/index.js +8 -2
- package/src/process/ProcessChild.js +2 -1
- package/src/process/ProcessWorker.js +1 -1
- package/src/threads/ThreadsWorker.js +2 -2
- package/src/types.js +1 -1
- package/src/web/WebChild.js +50 -0
- package/src/web/WebWorker.js +85 -0
- package/test/cpuCount.test.js +1 -1
- package/test/integration/workerfarm/console.js +1 -1
- package/test/integration/workerfarm/logging.js +1 -1
- package/test/integration/workerfarm/reverse-handle.js +2 -2
- package/test/workerfarm.js +5 -5
- package/lib/Profiler.js +0 -70
- package/lib/Trace.js +0 -126
- package/src/Profiler.js +0 -93
- package/src/Trace.js +0 -121
package/src/Handle.js
CHANGED
@@ -1,20 +1,16 @@
|
|
1
|
-
// @flow
|
2
|
-
|
3
|
-
import type {WorkerApi} from './';
|
4
|
-
|
1
|
+
// @flow strict-local
|
5
2
|
import {registerSerializableClass} from '@parcel/core';
|
6
|
-
|
7
|
-
import {child} from './childState';
|
3
|
+
// $FlowFixMe
|
8
4
|
import packageJson from '../package.json';
|
9
5
|
|
10
6
|
let HANDLE_ID = 0;
|
11
|
-
|
7
|
+
// $FlowFixMe
|
12
8
|
export type HandleFunction = (...args: Array<any>) => any;
|
13
9
|
|
14
10
|
type HandleOpts = {|
|
15
|
-
fn
|
11
|
+
fn?: HandleFunction,
|
16
12
|
childId?: ?number,
|
17
|
-
|
13
|
+
id?: number,
|
18
14
|
|};
|
19
15
|
|
20
16
|
const handleById: Map<number, Handle> = new Map();
|
@@ -22,14 +18,12 @@ const handleById: Map<number, Handle> = new Map();
|
|
22
18
|
export default class Handle {
|
23
19
|
id: number;
|
24
20
|
childId: ?number;
|
25
|
-
fn: HandleFunction;
|
26
|
-
workerApi: WorkerApi;
|
21
|
+
fn: ?HandleFunction;
|
27
22
|
|
28
23
|
constructor(opts: HandleOpts) {
|
29
|
-
this.id = ++HANDLE_ID;
|
24
|
+
this.id = opts.id ?? ++HANDLE_ID;
|
30
25
|
this.fn = opts.fn;
|
31
26
|
this.childId = opts.childId;
|
32
|
-
this.workerApi = opts.workerApi;
|
33
27
|
handleById.set(this.id, this);
|
34
28
|
}
|
35
29
|
|
@@ -37,38 +31,15 @@ export default class Handle {
|
|
37
31
|
handleById.delete(this.id);
|
38
32
|
}
|
39
33
|
|
40
|
-
serialize() {
|
34
|
+
serialize(): {|childId: ?number, id: number|} {
|
41
35
|
return {
|
42
36
|
id: this.id,
|
43
37
|
childId: this.childId,
|
44
38
|
};
|
45
39
|
}
|
46
40
|
|
47
|
-
static deserialize(opts:
|
48
|
-
return
|
49
|
-
let workerApi;
|
50
|
-
if (child) {
|
51
|
-
workerApi = child.workerApi;
|
52
|
-
} else {
|
53
|
-
let handle = handleById.get(opts.id);
|
54
|
-
if (!handle) {
|
55
|
-
throw new Error(
|
56
|
-
'Corresponding Handle was not found. It may have been disposed.',
|
57
|
-
);
|
58
|
-
}
|
59
|
-
workerApi = handle.workerApi;
|
60
|
-
}
|
61
|
-
|
62
|
-
if (opts.childId != null && child) {
|
63
|
-
throw new Error('Cannot call another child from a child');
|
64
|
-
}
|
65
|
-
|
66
|
-
if (opts.childId != null && workerApi.callChild) {
|
67
|
-
return workerApi.callChild(opts.childId, {handle: opts.id, args});
|
68
|
-
}
|
69
|
-
|
70
|
-
return workerApi.callMaster({handle: opts.id, args}, true);
|
71
|
-
};
|
41
|
+
static deserialize(opts: HandleOpts): Handle {
|
42
|
+
return new Handle(opts);
|
72
43
|
}
|
73
44
|
}
|
74
45
|
|
package/src/Worker.js
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
// @flow
|
2
2
|
|
3
3
|
import type {FilePath} from '@parcel/types';
|
4
|
-
import type {
|
4
|
+
import type {BackendType, WorkerImpl, WorkerMessage} from './types';
|
5
|
+
import type {SharedReference} from './WorkerFarm';
|
5
6
|
|
7
|
+
import nullthrows from 'nullthrows';
|
6
8
|
import EventEmitter from 'events';
|
7
9
|
import ThrowableDiagnostic from '@parcel/diagnostic';
|
8
10
|
import {getWorkerBackend} from './backend';
|
@@ -12,6 +14,7 @@ export type WorkerCall = {|
|
|
12
14
|
handle?: number,
|
13
15
|
args: $ReadOnlyArray<any>,
|
14
16
|
retries: number,
|
17
|
+
skipReadyCheck?: boolean,
|
15
18
|
resolve: (result: Promise<any> | any) => void,
|
16
19
|
reject: (error: any) => void,
|
17
20
|
|};
|
@@ -19,7 +22,9 @@ export type WorkerCall = {|
|
|
19
22
|
type WorkerOpts = {|
|
20
23
|
forcedKillTime: number,
|
21
24
|
backend: BackendType,
|
22
|
-
|
25
|
+
shouldPatchConsole?: boolean,
|
26
|
+
shouldTrace?: boolean,
|
27
|
+
sharedReferences: $ReadOnlyMap<SharedReference, mixed>,
|
23
28
|
|};
|
24
29
|
|
25
30
|
let WORKER_ID = 0;
|
@@ -27,14 +32,15 @@ export default class Worker extends EventEmitter {
|
|
27
32
|
+options: WorkerOpts;
|
28
33
|
worker: WorkerImpl;
|
29
34
|
id: number = WORKER_ID++;
|
35
|
+
sentSharedReferences: Set<SharedReference> = new Set();
|
30
36
|
|
31
37
|
calls: Map<number, WorkerCall> = new Map();
|
32
|
-
exitCode = null;
|
33
|
-
callId = 0;
|
38
|
+
exitCode: ?number = null;
|
39
|
+
callId: number = 0;
|
34
40
|
|
35
|
-
ready = false;
|
36
|
-
stopped = false;
|
37
|
-
isStopping = false;
|
41
|
+
ready: boolean = false;
|
42
|
+
stopped: boolean = false;
|
43
|
+
isStopping: boolean = false;
|
38
44
|
|
39
45
|
constructor(options: WorkerOpts) {
|
40
46
|
super();
|
@@ -42,18 +48,46 @@ export default class Worker extends EventEmitter {
|
|
42
48
|
}
|
43
49
|
|
44
50
|
async fork(forkModule: FilePath) {
|
45
|
-
let filteredArgs =
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
let filteredArgs = [];
|
52
|
+
if (process.execArgv) {
|
53
|
+
filteredArgs = process.execArgv.filter(
|
54
|
+
v => !/^--(debug|inspect|no-opt|max-old-space-size=)/.test(v),
|
55
|
+
);
|
56
|
+
|
57
|
+
for (let i = 0; i < filteredArgs.length; i++) {
|
58
|
+
let arg = filteredArgs[i];
|
59
|
+
let isArgWithParam =
|
60
|
+
((arg === '-r' || arg === '--require') &&
|
61
|
+
filteredArgs[i + 1] === '@parcel/register') ||
|
62
|
+
arg === '--title';
|
63
|
+
if (isArgWithParam) {
|
64
|
+
filteredArgs.splice(i, 2);
|
65
|
+
i--;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
// Workaround for https://github.com/nodejs/node/issues/29117
|
71
|
+
if (process.env.NODE_OPTIONS) {
|
72
|
+
// arg parsing logic adapted from https://stackoverflow.com/a/46946420/2352201
|
73
|
+
let opts = [''];
|
74
|
+
let quote = false;
|
75
|
+
for (let c of nullthrows(process.env.NODE_OPTIONS.match(/.|^$/g))) {
|
76
|
+
if (c === '"') {
|
77
|
+
quote = !quote;
|
78
|
+
} else if (!quote && c === ' ') {
|
79
|
+
opts.push('');
|
80
|
+
} else {
|
81
|
+
opts[opts.length - 1] += c.replace(/\\(.)/, '$1');
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
for (let i = 0; i < opts.length; i++) {
|
86
|
+
let opt = opts[i];
|
87
|
+
if (opt === '-r' || opt === '--require') {
|
88
|
+
filteredArgs.push(opt, opts[i + 1]);
|
89
|
+
i++;
|
90
|
+
}
|
57
91
|
}
|
58
92
|
}
|
59
93
|
|
@@ -77,19 +111,49 @@ export default class Worker extends EventEmitter {
|
|
77
111
|
args: [
|
78
112
|
forkModule,
|
79
113
|
{
|
80
|
-
|
114
|
+
shouldPatchConsole: !!this.options.shouldPatchConsole,
|
115
|
+
shouldTrace: !!this.options.shouldTrace,
|
81
116
|
},
|
82
117
|
],
|
83
118
|
retries: 0,
|
119
|
+
skipReadyCheck: true,
|
84
120
|
resolve,
|
85
121
|
reject,
|
86
122
|
});
|
87
123
|
});
|
88
124
|
|
125
|
+
let sharedRefs = this.options.sharedReferences;
|
126
|
+
let refsShared = new Set();
|
127
|
+
// in case more refs are created while initial refs are sending
|
128
|
+
while (refsShared.size < sharedRefs.size) {
|
129
|
+
await Promise.all(
|
130
|
+
[...sharedRefs]
|
131
|
+
.filter(([ref]) => !refsShared.has(ref))
|
132
|
+
.map(async ([ref, value]) => {
|
133
|
+
await this.sendSharedReference(ref, value);
|
134
|
+
refsShared.add(ref);
|
135
|
+
}),
|
136
|
+
);
|
137
|
+
}
|
138
|
+
|
89
139
|
this.ready = true;
|
90
140
|
this.emit('ready');
|
91
141
|
}
|
92
142
|
|
143
|
+
sendSharedReference(ref: SharedReference, value: mixed): Promise<any> {
|
144
|
+
this.sentSharedReferences.add(ref);
|
145
|
+
return new Promise((resolve, reject) => {
|
146
|
+
this.call({
|
147
|
+
method: 'createSharedReference',
|
148
|
+
args: [ref, value],
|
149
|
+
resolve,
|
150
|
+
reject,
|
151
|
+
retries: 0,
|
152
|
+
skipReadyCheck: true,
|
153
|
+
});
|
154
|
+
});
|
155
|
+
}
|
156
|
+
|
93
157
|
send(data: WorkerMessage): void {
|
94
158
|
this.worker.send(data);
|
95
159
|
}
|
@@ -102,14 +166,20 @@ export default class Worker extends EventEmitter {
|
|
102
166
|
let idx = this.callId++;
|
103
167
|
this.calls.set(idx, call);
|
104
168
|
|
105
|
-
|
169
|
+
let msg = {
|
106
170
|
type: 'request',
|
107
171
|
idx: idx,
|
108
172
|
child: this.id,
|
109
173
|
handle: call.handle,
|
110
174
|
method: call.method,
|
111
175
|
args: call.args,
|
112
|
-
}
|
176
|
+
};
|
177
|
+
|
178
|
+
if (this.ready || call.skipReadyCheck === true) {
|
179
|
+
this.send(msg);
|
180
|
+
} else {
|
181
|
+
this.once('ready', () => this.send(msg));
|
182
|
+
}
|
113
183
|
}
|
114
184
|
|
115
185
|
receive(message: WorkerMessage): void {
|