@parcel/workers 2.0.0-nightly.149 → 2.0.0-nightly.1490
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 +103 -62
- package/lib/WorkerFarm.js +272 -192
- package/lib/backend.js +4 -6
- package/lib/bus.js +11 -13
- package/lib/child.js +140 -116
- package/lib/childState.js +2 -4
- 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 +35 -32
- 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 +95 -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/child.js
CHANGED
@@ -9,16 +9,21 @@ import type {
|
|
9
9
|
WorkerResponse,
|
10
10
|
ChildImpl,
|
11
11
|
} from './types';
|
12
|
-
import type {IDisposable} from '@parcel/types';
|
13
|
-
import type {
|
12
|
+
import type {Async, IDisposable} from '@parcel/types';
|
13
|
+
import type {SharedReference} from './WorkerFarm';
|
14
14
|
|
15
|
+
import * as coreWorker from './core-worker';
|
15
16
|
import invariant from 'assert';
|
16
17
|
import nullthrows from 'nullthrows';
|
17
18
|
import Logger, {patchConsole, unpatchConsole} from '@parcel/logger';
|
18
19
|
import ThrowableDiagnostic, {anyToDiagnostic} from '@parcel/diagnostic';
|
20
|
+
import {deserialize} from '@parcel/core';
|
19
21
|
import bus from './bus';
|
20
|
-
import
|
21
|
-
import
|
22
|
+
import {SamplingProfiler, tracer} from '@parcel/profiler';
|
23
|
+
import _Handle from './Handle';
|
24
|
+
|
25
|
+
// The import of './Handle' should really be imported eagerly (with @babel/plugin-transform-modules-commonjs's lazy mode).
|
26
|
+
const Handle = _Handle;
|
22
27
|
|
23
28
|
type ChildCall = WorkerRequest & {|
|
24
29
|
resolve: (result: Promise<any> | any) => void,
|
@@ -30,20 +35,22 @@ export class Child {
|
|
30
35
|
childId: ?number;
|
31
36
|
maxConcurrentCalls: number = 10;
|
32
37
|
module: ?any;
|
33
|
-
responseId = 0;
|
38
|
+
responseId: number = 0;
|
34
39
|
responseQueue: Map<number, ChildCall> = new Map();
|
35
40
|
loggerDisposable: IDisposable;
|
41
|
+
tracerDisposable: IDisposable;
|
36
42
|
child: ChildImpl;
|
37
|
-
profiler: ?
|
38
|
-
workerApi: WorkerApi;
|
43
|
+
profiler: ?SamplingProfiler;
|
39
44
|
handles: Map<number, Handle> = new Map();
|
40
|
-
sharedReferences: Map<
|
41
|
-
sharedReferencesByValue: Map<mixed,
|
45
|
+
sharedReferences: Map<SharedReference, mixed> = new Map();
|
46
|
+
sharedReferencesByValue: Map<mixed, SharedReference> = new Map();
|
42
47
|
|
43
48
|
constructor(ChildBackend: Class<ChildImpl>) {
|
44
49
|
this.child = new ChildBackend(
|
45
|
-
|
46
|
-
|
50
|
+
m => {
|
51
|
+
this.messageListener(m);
|
52
|
+
},
|
53
|
+
() => this.handleEnd(),
|
47
54
|
);
|
48
55
|
|
49
56
|
// Monitior all logging events inside this child process and forward to
|
@@ -51,21 +58,37 @@ export class Child {
|
|
51
58
|
this.loggerDisposable = Logger.onLog(event => {
|
52
59
|
bus.emit('logEvent', event);
|
53
60
|
});
|
61
|
+
// .. and do the same for trace events
|
62
|
+
this.tracerDisposable = tracer.onTrace(event => {
|
63
|
+
bus.emit('traceEvent', event);
|
64
|
+
});
|
54
65
|
}
|
55
66
|
|
56
|
-
workerApi
|
67
|
+
workerApi: {|
|
68
|
+
callMaster: (
|
69
|
+
request: CallRequest,
|
70
|
+
awaitResponse?: ?boolean,
|
71
|
+
) => Promise<mixed>,
|
72
|
+
createReverseHandle: (fn: (...args: Array<any>) => mixed) => Handle,
|
73
|
+
getSharedReference: (ref: SharedReference) => mixed,
|
74
|
+
resolveSharedReference: (value: mixed) => void | SharedReference,
|
75
|
+
runHandle: (handle: Handle, args: Array<any>) => Promise<mixed>,
|
76
|
+
|} = {
|
57
77
|
callMaster: (
|
58
78
|
request: CallRequest,
|
59
79
|
awaitResponse: ?boolean = true,
|
60
80
|
): Promise<mixed> => this.addCall(request, awaitResponse),
|
61
81
|
createReverseHandle: (fn: (...args: Array<any>) => mixed): Handle =>
|
62
82
|
this.createReverseHandle(fn),
|
63
|
-
|
83
|
+
runHandle: (handle: Handle, args: Array<any>): Promise<mixed> =>
|
84
|
+
this.workerApi.callMaster({handle: handle.id, args}, true),
|
85
|
+
getSharedReference: (ref: SharedReference) =>
|
86
|
+
this.sharedReferences.get(ref),
|
64
87
|
resolveSharedReference: (value: mixed) =>
|
65
88
|
this.sharedReferencesByValue.get(value),
|
66
89
|
};
|
67
90
|
|
68
|
-
messageListener(message: WorkerMessage):
|
91
|
+
messageListener(message: WorkerMessage): Async<void> {
|
69
92
|
if (message.type === 'response') {
|
70
93
|
return this.handleResponse(message);
|
71
94
|
} else if (message.type === 'request') {
|
@@ -77,10 +100,23 @@ export class Child {
|
|
77
100
|
this.child.send(data);
|
78
101
|
}
|
79
102
|
|
80
|
-
childInit(module: string, childId: number): void {
|
81
|
-
// $FlowFixMe
|
82
|
-
|
103
|
+
async childInit(module: string, childId: number): Promise<void> {
|
104
|
+
// $FlowFixMe
|
105
|
+
if (process.browser) {
|
106
|
+
if (module === '@parcel/core/src/worker.js') {
|
107
|
+
this.module = coreWorker;
|
108
|
+
} else {
|
109
|
+
throw new Error('No dynamic require possible: ' + module);
|
110
|
+
}
|
111
|
+
} else {
|
112
|
+
// $FlowFixMe this must be dynamic
|
113
|
+
this.module = require(module);
|
114
|
+
}
|
83
115
|
this.childId = childId;
|
116
|
+
|
117
|
+
if (this.module.childInit != null) {
|
118
|
+
await this.module.childInit();
|
119
|
+
}
|
84
120
|
}
|
85
121
|
|
86
122
|
async handleRequest(data: WorkerRequest): Promise<void> {
|
@@ -106,7 +142,7 @@ export class Child {
|
|
106
142
|
let result;
|
107
143
|
if (handleId != null) {
|
108
144
|
try {
|
109
|
-
let fn = nullthrows(this.handles.get(handleId))
|
145
|
+
let fn = nullthrows(this.handles.get(handleId)?.fn);
|
110
146
|
result = responseFromContent(fn(...args));
|
111
147
|
} catch (e) {
|
112
148
|
result = errorResponseFromError(e);
|
@@ -114,18 +150,22 @@ export class Child {
|
|
114
150
|
} else if (method === 'childInit') {
|
115
151
|
try {
|
116
152
|
let [moduleName, childOptions] = args;
|
117
|
-
if (childOptions.
|
153
|
+
if (childOptions.shouldPatchConsole) {
|
118
154
|
patchConsole();
|
119
155
|
} else {
|
120
156
|
unpatchConsole();
|
121
157
|
}
|
122
158
|
|
123
|
-
|
159
|
+
if (childOptions.shouldTrace) {
|
160
|
+
tracer.enable();
|
161
|
+
}
|
162
|
+
|
163
|
+
result = responseFromContent(await this.childInit(moduleName, child));
|
124
164
|
} catch (e) {
|
125
165
|
result = errorResponseFromError(e);
|
126
166
|
}
|
127
167
|
} else if (method === 'startProfile') {
|
128
|
-
this.profiler = new
|
168
|
+
this.profiler = new SamplingProfiler();
|
129
169
|
try {
|
130
170
|
result = responseFromContent(await this.profiler.startProfiling());
|
131
171
|
} catch (e) {
|
@@ -138,13 +178,37 @@ export class Child {
|
|
138
178
|
} catch (e) {
|
139
179
|
result = errorResponseFromError(e);
|
140
180
|
}
|
181
|
+
} else if (method === 'takeHeapSnapshot') {
|
182
|
+
try {
|
183
|
+
let v8 = require('v8');
|
184
|
+
result = responseFromContent(
|
185
|
+
v8.writeHeapSnapshot(
|
186
|
+
'heap-' +
|
187
|
+
args[0] +
|
188
|
+
'-' +
|
189
|
+
(this.childId ? 'worker' + this.childId : 'main') +
|
190
|
+
'.heapsnapshot',
|
191
|
+
),
|
192
|
+
);
|
193
|
+
} catch (e) {
|
194
|
+
result = errorResponseFromError(e);
|
195
|
+
}
|
141
196
|
} else if (method === 'createSharedReference') {
|
142
|
-
let [ref,
|
197
|
+
let [ref, _value] = args;
|
198
|
+
let value =
|
199
|
+
_value instanceof ArrayBuffer
|
200
|
+
? // In the case the value is pre-serialized as a buffer,
|
201
|
+
// deserialize it.
|
202
|
+
deserialize(Buffer.from(_value))
|
203
|
+
: _value;
|
143
204
|
this.sharedReferences.set(ref, value);
|
144
205
|
this.sharedReferencesByValue.set(value, ref);
|
145
206
|
result = responseFromContent(null);
|
146
207
|
} else if (method === 'deleteSharedReference') {
|
147
|
-
|
208
|
+
let ref = args[0];
|
209
|
+
let value = this.sharedReferences.get(ref);
|
210
|
+
this.sharedReferencesByValue.delete(value);
|
211
|
+
this.sharedReferences.delete(ref);
|
148
212
|
result = responseFromContent(null);
|
149
213
|
} else {
|
150
214
|
try {
|
@@ -157,7 +221,11 @@ export class Child {
|
|
157
221
|
}
|
158
222
|
}
|
159
223
|
|
160
|
-
|
224
|
+
try {
|
225
|
+
this.send(result);
|
226
|
+
} catch (e) {
|
227
|
+
result = this.send(errorResponseFromError(e));
|
228
|
+
}
|
161
229
|
}
|
162
230
|
|
163
231
|
handleResponse(data: WorkerResponse): void {
|
@@ -189,6 +257,7 @@ export class Child {
|
|
189
257
|
...request,
|
190
258
|
type: 'request',
|
191
259
|
child: this.childId,
|
260
|
+
// $FlowFixMe Added in Flow 0.121.0 upgrade in #4381
|
192
261
|
awaitResponse,
|
193
262
|
resolve: () => {},
|
194
263
|
reject: () => {},
|
@@ -239,12 +308,12 @@ export class Child {
|
|
239
308
|
|
240
309
|
handleEnd(): void {
|
241
310
|
this.loggerDisposable.dispose();
|
311
|
+
this.tracerDisposable.dispose();
|
242
312
|
}
|
243
313
|
|
244
|
-
createReverseHandle(fn: (...args: Array<any>) => mixed) {
|
314
|
+
createReverseHandle(fn: (...args: Array<any>) => mixed): Handle {
|
245
315
|
let handle = new Handle({
|
246
316
|
fn,
|
247
|
-
workerApi: this.workerApi,
|
248
317
|
childId: this.childId,
|
249
318
|
});
|
250
319
|
this.handles.set(handle.id, handle);
|
package/src/cpuCount.js
CHANGED
@@ -26,6 +26,11 @@ export function detectRealCores(): number {
|
|
26
26
|
);
|
27
27
|
} else if (platform === 'darwin') {
|
28
28
|
amount = parseInt(exec('sysctl -n hw.physicalcpu_max'), 10);
|
29
|
+
} else if (platform === 'win32') {
|
30
|
+
const str = exec('wmic cpu get NumberOfCores').match(/\d+/g);
|
31
|
+
if (str !== null) {
|
32
|
+
amount = parseInt(str.filter(n => n !== '')[0], 10);
|
33
|
+
}
|
29
34
|
}
|
30
35
|
|
31
36
|
if (!amount || amount <= 0) {
|
@@ -36,21 +41,29 @@ export function detectRealCores(): number {
|
|
36
41
|
}
|
37
42
|
|
38
43
|
let cores;
|
39
|
-
export default function getCores(bypassCache?: boolean = false) {
|
44
|
+
export default function getCores(bypassCache?: boolean = false): number {
|
40
45
|
// Do not re-run commands if we already have the count...
|
41
|
-
// $FlowFixMe
|
42
46
|
if (cores && !bypassCache) {
|
43
47
|
return cores;
|
44
48
|
}
|
45
49
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
// $FlowFixMe
|
51
|
+
if (process.browser) {
|
52
|
+
// eslint-disable-next-line no-undef
|
53
|
+
cores = navigator.hardwareConcurrency / 2;
|
54
|
+
}
|
55
|
+
|
56
|
+
if (!cores) {
|
57
|
+
try {
|
58
|
+
cores = detectRealCores();
|
59
|
+
} catch (e) {
|
60
|
+
// Guess the amount of real cores
|
61
|
+
cores = os
|
62
|
+
.cpus()
|
63
|
+
.filter(
|
64
|
+
(cpu, index) => !cpu.model.includes('Intel') || index % 2 === 1,
|
65
|
+
).length;
|
66
|
+
}
|
54
67
|
}
|
55
68
|
|
56
69
|
// Another fallback
|
package/src/index.js
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
// @flow
|
2
|
-
import type {LogEvent} from '@parcel/types';
|
2
|
+
import type {TraceEvent, LogEvent} from '@parcel/types';
|
3
3
|
import invariant from 'assert';
|
4
4
|
import WorkerFarm from './WorkerFarm';
|
5
5
|
import Logger from '@parcel/logger';
|
6
6
|
import bus from './bus';
|
7
|
+
import {tracer} from '@parcel/profiler';
|
7
8
|
|
8
9
|
if (!WorkerFarm.isWorker()) {
|
9
10
|
// Forward all logger events originating from workers into the main process
|
@@ -29,9 +30,14 @@ if (!WorkerFarm.isWorker()) {
|
|
29
30
|
throw new Error('Unknown log level');
|
30
31
|
}
|
31
32
|
});
|
33
|
+
|
34
|
+
// Forward all trace events originating from workers into the main process
|
35
|
+
bus.on('traceEvent', (e: TraceEvent) => {
|
36
|
+
tracer.trace(e);
|
37
|
+
});
|
32
38
|
}
|
33
39
|
|
34
40
|
export default WorkerFarm;
|
35
41
|
export {bus};
|
36
42
|
export {Handle} from './WorkerFarm';
|
37
|
-
export type {WorkerApi, FarmOptions} from './WorkerFarm';
|
43
|
+
export type {WorkerApi, FarmOptions, SharedReference} from './WorkerFarm';
|
@@ -25,7 +25,7 @@ export default class ProcessChild implements ChildImpl {
|
|
25
25
|
process.on('message', data => this.handleMessage(data));
|
26
26
|
}
|
27
27
|
|
28
|
-
handleMessage(data: string) {
|
28
|
+
handleMessage(data: string): void {
|
29
29
|
if (data === 'die') {
|
30
30
|
return this.stop();
|
31
31
|
}
|
@@ -37,6 +37,7 @@ export default class ProcessChild implements ChildImpl {
|
|
37
37
|
let processSend = nullthrows(process.send).bind(process);
|
38
38
|
processSend(serialize(data).toString('base64'), err => {
|
39
39
|
if (err && err instanceof Error) {
|
40
|
+
// $FlowFixMe[prop-missing]
|
40
41
|
if (err.code === 'ERR_IPC_CHANNEL_CLOSED') {
|
41
42
|
// IPC connection closed
|
42
43
|
// no need to keep the worker running if it can't send or receive data
|
@@ -32,7 +32,7 @@ export default class ThreadsWorker implements WorkerImpl {
|
|
32
32
|
this.onExit = onExit;
|
33
33
|
}
|
34
34
|
|
35
|
-
start() {
|
35
|
+
start(): Promise<void> {
|
36
36
|
this.worker = new Worker(WORKER_PATH, {
|
37
37
|
execArgv: this.execArgv,
|
38
38
|
env: process.env,
|
@@ -47,7 +47,7 @@ export default class ThreadsWorker implements WorkerImpl {
|
|
47
47
|
});
|
48
48
|
}
|
49
49
|
|
50
|
-
stop() {
|
50
|
+
stop(): Promise<void> {
|
51
51
|
// In node 12, this returns a promise, but previously it accepted a callback
|
52
52
|
// TODO: Pass a callback in earlier versions of Node
|
53
53
|
return Promise.resolve(this.worker.terminate());
|
package/src/types.js
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
// @flow
|
2
|
+
/* eslint-env worker*/
|
3
|
+
|
4
|
+
import type {
|
5
|
+
ChildImpl,
|
6
|
+
MessageHandler,
|
7
|
+
ExitHandler,
|
8
|
+
WorkerMessage,
|
9
|
+
} from '../types';
|
10
|
+
import {setChild} from '../childState';
|
11
|
+
import {Child} from '../child';
|
12
|
+
import {prepareForSerialization, restoreDeserializedObject} from '@parcel/core';
|
13
|
+
|
14
|
+
export default class WebChild implements ChildImpl {
|
15
|
+
onMessage: MessageHandler;
|
16
|
+
onExit: ExitHandler;
|
17
|
+
|
18
|
+
constructor(onMessage: MessageHandler, onExit: ExitHandler) {
|
19
|
+
if (
|
20
|
+
!(
|
21
|
+
typeof WorkerGlobalScope !== 'undefined' &&
|
22
|
+
self instanceof WorkerGlobalScope
|
23
|
+
)
|
24
|
+
) {
|
25
|
+
throw new Error('Only create WebChild instances in a worker!');
|
26
|
+
}
|
27
|
+
|
28
|
+
this.onMessage = onMessage;
|
29
|
+
this.onExit = onExit;
|
30
|
+
self.addEventListener('message', ({data}: MessageEvent) => {
|
31
|
+
if (data === 'stop') {
|
32
|
+
this.onExit(0);
|
33
|
+
self.postMessage('stopped');
|
34
|
+
}
|
35
|
+
// $FlowFixMe assume WorkerMessage as data
|
36
|
+
this.handleMessage(data);
|
37
|
+
});
|
38
|
+
self.postMessage('online');
|
39
|
+
}
|
40
|
+
|
41
|
+
handleMessage(data: WorkerMessage) {
|
42
|
+
this.onMessage(restoreDeserializedObject(data));
|
43
|
+
}
|
44
|
+
|
45
|
+
send(data: WorkerMessage) {
|
46
|
+
self.postMessage(prepareForSerialization(data));
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
setChild(new Child(WebChild));
|
@@ -0,0 +1,85 @@
|
|
1
|
+
// @flow
|
2
|
+
|
3
|
+
import type {
|
4
|
+
WorkerImpl,
|
5
|
+
MessageHandler,
|
6
|
+
ErrorHandler,
|
7
|
+
ExitHandler,
|
8
|
+
WorkerMessage,
|
9
|
+
} from '../types';
|
10
|
+
import {prepareForSerialization, restoreDeserializedObject} from '@parcel/core';
|
11
|
+
import {makeDeferredWithPromise} from '@parcel/utils';
|
12
|
+
|
13
|
+
let id = 0;
|
14
|
+
|
15
|
+
export default class WebWorker implements WorkerImpl {
|
16
|
+
execArgv: Object;
|
17
|
+
onMessage: MessageHandler;
|
18
|
+
onError: ErrorHandler;
|
19
|
+
onExit: ExitHandler;
|
20
|
+
worker: Worker;
|
21
|
+
stopping: ?Promise<void>;
|
22
|
+
|
23
|
+
constructor(
|
24
|
+
execArgv: Object,
|
25
|
+
onMessage: MessageHandler,
|
26
|
+
onError: ErrorHandler,
|
27
|
+
onExit: ExitHandler,
|
28
|
+
) {
|
29
|
+
this.execArgv = execArgv;
|
30
|
+
this.onMessage = onMessage;
|
31
|
+
this.onError = onError;
|
32
|
+
this.onExit = onExit;
|
33
|
+
}
|
34
|
+
|
35
|
+
start(): Promise<void> {
|
36
|
+
// $FlowFixMe[incompatible-call]
|
37
|
+
this.worker = new Worker(new URL('./WebChild.js', import.meta.url), {
|
38
|
+
name: `Parcel Worker ${id++}`,
|
39
|
+
type: 'module',
|
40
|
+
});
|
41
|
+
|
42
|
+
let {deferred, promise} = makeDeferredWithPromise();
|
43
|
+
|
44
|
+
this.worker.onmessage = ({data}) => {
|
45
|
+
if (data === 'online') {
|
46
|
+
deferred.resolve();
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
|
50
|
+
// $FlowFixMe assume WorkerMessage as data
|
51
|
+
this.handleMessage(data);
|
52
|
+
};
|
53
|
+
this.worker.onerror = this.onError;
|
54
|
+
// Web workers can't crash or intentionally stop on their own, apart from stop() below
|
55
|
+
// this.worker.on('exit', this.onExit);
|
56
|
+
|
57
|
+
return promise;
|
58
|
+
}
|
59
|
+
|
60
|
+
stop(): Promise<void> {
|
61
|
+
if (!this.stopping) {
|
62
|
+
this.stopping = (async () => {
|
63
|
+
this.worker.postMessage('stop');
|
64
|
+
let {deferred, promise} = makeDeferredWithPromise();
|
65
|
+
this.worker.addEventListener('message', ({data}: MessageEvent) => {
|
66
|
+
if (data === 'stopped') {
|
67
|
+
deferred.resolve();
|
68
|
+
}
|
69
|
+
});
|
70
|
+
await promise;
|
71
|
+
this.worker.terminate();
|
72
|
+
this.onExit(0);
|
73
|
+
})();
|
74
|
+
}
|
75
|
+
return this.stopping;
|
76
|
+
}
|
77
|
+
|
78
|
+
handleMessage(data: WorkerMessage) {
|
79
|
+
this.onMessage(restoreDeserializedObject(data));
|
80
|
+
}
|
81
|
+
|
82
|
+
send(data: WorkerMessage) {
|
83
|
+
this.worker.postMessage(prepareForSerialization(data));
|
84
|
+
}
|
85
|
+
}
|
package/test/cpuCount.test.js
CHANGED
@@ -3,7 +3,7 @@ import os from 'os';
|
|
3
3
|
|
4
4
|
import getCores, {detectRealCores} from '../src/cpuCount';
|
5
5
|
|
6
|
-
describe('cpuCount', function() {
|
6
|
+
describe('cpuCount', function () {
|
7
7
|
it('Should be able to detect real cpu count', () => {
|
8
8
|
// Windows not supported as getting the cpu count takes a couple seconds...
|
9
9
|
if (os.platform() === 'win32') return;
|
package/test/workerfarm.js
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import Logger from '@parcel/logger';
|
2
2
|
import assert from 'assert';
|
3
|
-
import WorkerFarm from '../';
|
3
|
+
import WorkerFarm from '../src';
|
4
4
|
|
5
|
-
describe('WorkerFarm', function() {
|
5
|
+
describe('WorkerFarm', function () {
|
6
6
|
this.timeout(30000);
|
7
7
|
|
8
8
|
it('Should start up workers', async () => {
|
@@ -132,7 +132,7 @@ describe('WorkerFarm', function() {
|
|
132
132
|
await workerfarm.end();
|
133
133
|
});
|
134
134
|
|
135
|
-
it('Forwards stdio from the child process and levels event source if
|
135
|
+
it('Forwards stdio from the child process and levels event source if shouldPatchConsole is true', async () => {
|
136
136
|
let events = [];
|
137
137
|
let logDisposable = Logger.onLog(event => events.push(event));
|
138
138
|
|
@@ -140,7 +140,7 @@ describe('WorkerFarm', function() {
|
|
140
140
|
warmWorkers: true,
|
141
141
|
useLocalWorker: false,
|
142
142
|
workerPath: require.resolve('./integration/workerfarm/console.js'),
|
143
|
-
|
143
|
+
shouldPatchConsole: true,
|
144
144
|
});
|
145
145
|
|
146
146
|
await workerfarm.run();
|
@@ -291,7 +291,7 @@ describe('WorkerFarm', function() {
|
|
291
291
|
assert.equal(result, 'Shared reference does not exist');
|
292
292
|
});
|
293
293
|
|
294
|
-
it('
|
294
|
+
it('Should resolve shared references in workers', async () => {
|
295
295
|
let workerfarm = new WorkerFarm({
|
296
296
|
warmWorkers: true,
|
297
297
|
useLocalWorker: false,
|
package/lib/Profiler.js
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
4
|
-
value: true
|
5
|
-
});
|
6
|
-
exports.default = void 0;
|
7
|
-
|
8
|
-
var _assert = _interopRequireDefault(require("assert"));
|
9
|
-
|
10
|
-
var _diagnostic = _interopRequireDefault(require("@parcel/diagnostic"));
|
11
|
-
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
13
|
-
|
14
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
15
|
-
|
16
|
-
class Profiler {
|
17
|
-
constructor() {
|
18
|
-
_defineProperty(this, "session", void 0);
|
19
|
-
}
|
20
|
-
|
21
|
-
startProfiling() {
|
22
|
-
let inspector;
|
23
|
-
|
24
|
-
try {
|
25
|
-
inspector = require('inspector');
|
26
|
-
} catch (err) {
|
27
|
-
throw new _diagnostic.default({
|
28
|
-
diagnostic: {
|
29
|
-
message: `The inspector module isn't available`,
|
30
|
-
origin: '@parcel/workers',
|
31
|
-
hints: ['Disable build profiling']
|
32
|
-
}
|
33
|
-
});
|
34
|
-
}
|
35
|
-
|
36
|
-
this.session = new inspector.Session();
|
37
|
-
this.session.connect();
|
38
|
-
return Promise.all([this.sendCommand('Profiler.setSamplingInterval', {
|
39
|
-
interval: 100
|
40
|
-
}), this.sendCommand('Profiler.enable'), this.sendCommand('Profiler.start')]);
|
41
|
-
}
|
42
|
-
|
43
|
-
sendCommand(method, params) {
|
44
|
-
(0, _assert.default)(this.session != null);
|
45
|
-
return new Promise((resolve, reject) => {
|
46
|
-
this.session.post(method, params, (err, params) => {
|
47
|
-
if (err == null) {
|
48
|
-
resolve(params);
|
49
|
-
} else {
|
50
|
-
reject(err);
|
51
|
-
}
|
52
|
-
});
|
53
|
-
});
|
54
|
-
}
|
55
|
-
|
56
|
-
destroy() {
|
57
|
-
if (this.session != null) {
|
58
|
-
this.session.disconnect();
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
async stopProfiling() {
|
63
|
-
let res = await this.sendCommand('Profiler.stop');
|
64
|
-
this.destroy();
|
65
|
-
return res.profile;
|
66
|
-
}
|
67
|
-
|
68
|
-
}
|
69
|
-
|
70
|
-
exports.default = Profiler;
|