@parcel/workers 2.0.0-nightly.97 → 2.1.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/WorkerFarm.js CHANGED
@@ -11,15 +11,55 @@ Object.defineProperty(exports, "Handle", {
11
11
  });
12
12
  exports.default = void 0;
13
13
 
14
- var _assert = _interopRequireDefault(require("assert"));
14
+ function _assert() {
15
+ const data = _interopRequireDefault(require("assert"));
15
16
 
16
- var _nullthrows = _interopRequireDefault(require("nullthrows"));
17
+ _assert = function () {
18
+ return data;
19
+ };
17
20
 
18
- var _events = _interopRequireDefault(require("events"));
21
+ return data;
22
+ }
23
+
24
+ function _nullthrows() {
25
+ const data = _interopRequireDefault(require("nullthrows"));
26
+
27
+ _nullthrows = function () {
28
+ return data;
29
+ };
30
+
31
+ return data;
32
+ }
33
+
34
+ function _events() {
35
+ const data = _interopRequireDefault(require("events"));
36
+
37
+ _events = function () {
38
+ return data;
39
+ };
40
+
41
+ return data;
42
+ }
43
+
44
+ function _core() {
45
+ const data = require("@parcel/core");
46
+
47
+ _core = function () {
48
+ return data;
49
+ };
50
+
51
+ return data;
52
+ }
53
+
54
+ function _diagnostic() {
55
+ const data = _interopRequireWildcard(require("@parcel/diagnostic"));
19
56
 
20
- var _core = require("@parcel/core");
57
+ _diagnostic = function () {
58
+ return data;
59
+ };
21
60
 
22
- var _diagnostic = _interopRequireWildcard(require("@parcel/diagnostic"));
61
+ return data;
62
+ }
23
63
 
24
64
  var _Worker = _interopRequireDefault(require("./Worker"));
25
65
 
@@ -35,83 +75,58 @@ var _Profiler = _interopRequireDefault(require("./Profiler"));
35
75
 
36
76
  var _Trace = _interopRequireDefault(require("./Trace"));
37
77
 
38
- var _fs = _interopRequireDefault(require("fs"));
78
+ function _fs() {
79
+ const data = _interopRequireDefault(require("fs"));
39
80
 
40
- var _logger = _interopRequireDefault(require("@parcel/logger"));
81
+ _fs = function () {
82
+ return data;
83
+ };
41
84
 
42
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
85
+ return data;
86
+ }
43
87
 
44
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
88
+ function _logger() {
89
+ const data = _interopRequireDefault(require("@parcel/logger"));
45
90
 
46
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
91
+ _logger = function () {
92
+ return data;
93
+ };
94
+
95
+ return data;
96
+ }
47
97
 
48
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
98
+ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
49
99
 
50
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
100
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
51
101
 
52
- 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; }
102
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
53
103
 
54
- let profileId = 1;
55
104
  let referenceId = 1;
56
105
 
57
106
  /**
58
107
  * workerPath should always be defined inside farmOptions
59
108
  */
60
- class WorkerFarm extends _events.default {
109
+ class WorkerFarm extends _events().default {
110
+ callQueue = [];
111
+ ending = false;
112
+ warmWorkers = 0;
113
+ workers = new Map();
114
+ handles = new Map();
115
+ sharedReferences = new Map();
116
+ sharedReferencesByValue = new Map();
117
+
61
118
  constructor(farmOptions = {}) {
62
119
  super();
63
-
64
- _defineProperty(this, "callQueue", []);
65
-
66
- _defineProperty(this, "ending", false);
67
-
68
- _defineProperty(this, "localWorker", void 0);
69
-
70
- _defineProperty(this, "options", void 0);
71
-
72
- _defineProperty(this, "run", void 0);
73
-
74
- _defineProperty(this, "warmWorkers", 0);
75
-
76
- _defineProperty(this, "workers", new Map());
77
-
78
- _defineProperty(this, "handles", new Map());
79
-
80
- _defineProperty(this, "sharedReferences", new Map());
81
-
82
- _defineProperty(this, "sharedReferencesByValue", new Map());
83
-
84
- _defineProperty(this, "profiler", void 0);
85
-
86
- _defineProperty(this, "workerApi", {
87
- callMaster: async (request, awaitResponse = true) => {
88
- // $FlowFixMe
89
- let result = await this.processRequest(_objectSpread({}, request, {
90
- awaitResponse
91
- }));
92
- return (0, _core.deserialize)((0, _core.serialize)(result));
93
- },
94
- createReverseHandle: fn => this.createReverseHandle(fn),
95
- callChild: (childId, request) => new Promise((resolve, reject) => {
96
- (0, _nullthrows.default)(this.workers.get(childId)).call(_objectSpread({}, request, {
97
- resolve,
98
- reject,
99
- retries: 0
100
- }));
101
- }),
102
- getSharedReference: ref => this.sharedReferences.get(ref),
103
- resolveSharedReference: value => this.sharedReferencesByValue.get(value)
104
- });
105
-
106
- this.options = _objectSpread({
120
+ this.options = {
107
121
  maxConcurrentWorkers: WorkerFarm.getNumWorkers(),
108
122
  maxConcurrentCallsPerWorker: WorkerFarm.getConcurrentCallsPerWorker(),
109
123
  forcedKillTime: 500,
110
124
  warmWorkers: false,
111
125
  useLocalWorker: true,
112
126
  // TODO: setting this to false makes some tests fail, figure out why
113
- backend: (0, _backend.detectBackend)()
114
- }, farmOptions);
127
+ backend: (0, _backend.detectBackend)(),
128
+ ...farmOptions
129
+ };
115
130
 
116
131
  if (!this.options.workerPath) {
117
132
  throw new Error('Please provide a worker path!');
@@ -119,10 +134,35 @@ class WorkerFarm extends _events.default {
119
134
 
120
135
 
121
136
  this.localWorker = require(this.options.workerPath);
137
+ this.localWorkerInit = this.localWorker.childInit != null ? this.localWorker.childInit() : null;
122
138
  this.run = this.createHandle('run');
123
139
  this.startMaxWorkers();
124
140
  }
125
141
 
142
+ workerApi = {
143
+ callMaster: async (request, awaitResponse = true) => {
144
+ // $FlowFixMe
145
+ let result = await this.processRequest({ ...request,
146
+ awaitResponse
147
+ });
148
+ return (0, _core().deserialize)((0, _core().serialize)(result));
149
+ },
150
+ createReverseHandle: fn => this.createReverseHandle(fn),
151
+ callChild: (childId, request) => new Promise((resolve, reject) => {
152
+ (0, _nullthrows().default)(this.workers.get(childId)).call({ ...request,
153
+ resolve,
154
+ reject,
155
+ retries: 0
156
+ });
157
+ }),
158
+ runHandle: (handle, args) => this.workerApi.callChild((0, _nullthrows().default)(handle.childId), {
159
+ handle: handle.id,
160
+ args
161
+ }),
162
+ getSharedReference: ref => this.sharedReferences.get(ref),
163
+ resolveSharedReference: value => this.sharedReferencesByValue.get(value)
164
+ };
165
+
126
166
  warmupWorker(method, args) {
127
167
  // Workers are already stopping
128
168
  if (this.ending) {
@@ -150,7 +190,7 @@ class WorkerFarm extends _events.default {
150
190
  }
151
191
 
152
192
  createHandle(method) {
153
- return (...args) => {
193
+ return async (...args) => {
154
194
  // Child process workers are slow to start (~600ms).
155
195
  // While we're waiting, just run on the main thread.
156
196
  // This significantly speeds up startup time.
@@ -161,7 +201,13 @@ class WorkerFarm extends _events.default {
161
201
  this.warmupWorker(method, args);
162
202
  }
163
203
 
164
- let processedArgs = (0, _core.restoreDeserializedObject)((0, _core.prepareForSerialization)([...args, false]));
204
+ let processedArgs = (0, _core().restoreDeserializedObject)((0, _core().prepareForSerialization)([...args, false]));
205
+
206
+ if (this.localWorkerInit != null) {
207
+ await this.localWorkerInit;
208
+ this.localWorkerInit = null;
209
+ }
210
+
165
211
  return this.localWorker[method](this.workerApi, ...processedArgs);
166
212
  }
167
213
  };
@@ -171,6 +217,8 @@ class WorkerFarm extends _events.default {
171
217
  // Handle ipc errors
172
218
  if (error.code === 'ERR_IPC_CHANNEL_CLOSED') {
173
219
  return this.stopWorker(worker);
220
+ } else {
221
+ _logger().default.error(error, '@parcel/workers');
174
222
  }
175
223
  }
176
224
 
@@ -178,9 +226,10 @@ class WorkerFarm extends _events.default {
178
226
  let worker = new _Worker.default({
179
227
  forcedKillTime: this.options.forcedKillTime,
180
228
  backend: this.options.backend,
181
- patchConsole: this.options.patchConsole
229
+ shouldPatchConsole: this.options.shouldPatchConsole,
230
+ sharedReferences: this.sharedReferences
182
231
  });
183
- worker.fork((0, _nullthrows.default)(this.options.workerPath));
232
+ worker.fork((0, _nullthrows().default)(this.options.workerPath));
184
233
  worker.on('request', data => this.processRequest(data, worker));
185
234
  worker.on('ready', () => this.processQueue());
186
235
  worker.on('response', () => this.processQueue());
@@ -215,7 +264,9 @@ class WorkerFarm extends _events.default {
215
264
  this.startChild();
216
265
  }
217
266
 
218
- for (let worker of this.workers.values()) {
267
+ let workers = [...this.workers.values()].sort((a, b) => a.calls.size - b.calls.size);
268
+
269
+ for (let worker of workers) {
219
270
  if (!this.callQueue.length) {
220
271
  break;
221
272
  }
@@ -242,7 +293,9 @@ class WorkerFarm extends _events.default {
242
293
  let mod;
243
294
 
244
295
  if (handleId != null) {
245
- mod = (0, _nullthrows.default)(this.handles.get(handleId)).fn;
296
+ var _this$handles$get;
297
+
298
+ mod = (0, _nullthrows().default)((_this$handles$get = this.handles.get(handleId)) === null || _this$handles$get === void 0 ? void 0 : _this$handles$get.fn);
246
299
  } else if (location) {
247
300
  // $FlowFixMe this must be dynamic
248
301
  mod = require(location);
@@ -261,27 +314,26 @@ class WorkerFarm extends _events.default {
261
314
  idx,
262
315
  type: 'response',
263
316
  contentType: 'error',
264
- content: (0, _diagnostic.anyToDiagnostic)(e)
317
+ content: (0, _diagnostic().anyToDiagnostic)(e)
265
318
  });
266
319
 
267
320
  let result;
268
321
 
269
322
  if (method == null) {
270
323
  try {
271
- result = responseFromContent((await mod(...args)));
324
+ result = responseFromContent(await mod(...args));
272
325
  } catch (e) {
273
326
  result = errorResponseFromError(e);
274
327
  }
275
328
  } else {
276
329
  // ESModule default interop
277
- // $FlowFixMe
278
330
  if (mod.__esModule && !mod[method] && mod.default) {
279
331
  mod = mod.default;
280
332
  }
281
333
 
282
334
  try {
283
335
  // $FlowFixMe
284
- result = responseFromContent((await mod[method](...args)));
336
+ result = responseFromContent(await mod[method](...args));
285
337
  } catch (e) {
286
338
  result = errorResponseFromError(e);
287
339
  }
@@ -292,7 +344,7 @@ class WorkerFarm extends _events.default {
292
344
  worker.send(result);
293
345
  } else {
294
346
  if (result.contentType === 'error') {
295
- throw new _diagnostic.default({
347
+ throw new (_diagnostic().default)({
296
348
  diagnostic: result.content
297
349
  });
298
350
  }
@@ -321,6 +373,7 @@ class WorkerFarm extends _events.default {
321
373
 
322
374
  async end() {
323
375
  this.ending = true;
376
+ await Promise.all(Array.from(this.workers.values()).map(worker => this.stopWorker(worker)));
324
377
 
325
378
  for (let handle of this.handles.values()) {
326
379
  handle.dispose();
@@ -329,7 +382,6 @@ class WorkerFarm extends _events.default {
329
382
  this.handles = new Map();
330
383
  this.sharedReferences = new Map();
331
384
  this.sharedReferencesByValue = new Map();
332
- await Promise.all(Array.from(this.workers.values()).map(worker => this.stopWorker(worker)));
333
385
  this.ending = false;
334
386
  }
335
387
 
@@ -350,29 +402,25 @@ class WorkerFarm extends _events.default {
350
402
 
351
403
  createReverseHandle(fn) {
352
404
  let handle = new _Handle.default({
353
- fn,
354
- workerApi: this.workerApi
405
+ fn
355
406
  });
356
407
  this.handles.set(handle.id, handle);
357
408
  return handle;
358
409
  }
359
410
 
360
- async createSharedReference(value) {
411
+ async createSharedReference(value, // An optional, pre-serialized representation of the value to be used
412
+ // in its place.
413
+ buffer) {
361
414
  let ref = referenceId++;
362
415
  this.sharedReferences.set(ref, value);
363
416
  this.sharedReferencesByValue.set(value, ref);
417
+ let toSend = buffer ? buffer.buffer : value;
364
418
  let promises = [];
365
419
 
366
420
  for (let worker of this.workers.values()) {
367
- promises.push(new Promise((resolve, reject) => {
368
- worker.call({
369
- method: 'createSharedReference',
370
- args: [ref, value],
371
- resolve,
372
- reject,
373
- retries: 0
374
- });
375
- }));
421
+ if (worker.ready) {
422
+ promises.push(worker.sendSharedReference(ref, toSend));
423
+ }
376
424
  }
377
425
 
378
426
  await Promise.all(promises);
@@ -390,6 +438,7 @@ class WorkerFarm extends _events.default {
390
438
  args: [ref],
391
439
  resolve,
392
440
  reject,
441
+ skipReadyCheck: true,
393
442
  retries: 0
394
443
  });
395
444
  }));
@@ -410,7 +459,8 @@ class WorkerFarm extends _events.default {
410
459
  args: [],
411
460
  resolve,
412
461
  reject,
413
- retries: 0
462
+ retries: 0,
463
+ skipReadyCheck: true
414
464
  });
415
465
  }));
416
466
  }
@@ -436,15 +486,16 @@ class WorkerFarm extends _events.default {
436
486
  args: [],
437
487
  resolve,
438
488
  reject,
439
- retries: 0
489
+ retries: 0,
490
+ skipReadyCheck: true
440
491
  });
441
492
  }));
442
493
  }
443
494
 
444
495
  var profiles = await Promise.all(promises);
445
496
  let trace = new _Trace.default();
446
- let filename = `profile-${profileId++}.trace`;
447
- let stream = trace.pipe(_fs.default.createWriteStream(filename));
497
+ let filename = `profile-${getTimeId()}.trace`;
498
+ let stream = trace.pipe(_fs().default.createWriteStream(filename));
448
499
 
449
500
  for (let profile of profiles) {
450
501
  trace.addCPUProfile(names.shift(), profile);
@@ -455,14 +506,60 @@ class WorkerFarm extends _events.default {
455
506
  stream.once('finish', resolve);
456
507
  });
457
508
 
458
- _logger.default.info({
509
+ _logger().default.info({
459
510
  origin: '@parcel/workers',
460
- message: `Wrote profile to ${filename}`
511
+ message: (0, _diagnostic().md)`Wrote profile to ${filename}`
461
512
  });
462
513
  }
463
514
 
515
+ async callAllWorkers(method, args) {
516
+ let promises = [];
517
+
518
+ for (let worker of this.workers.values()) {
519
+ promises.push(new Promise((resolve, reject) => {
520
+ worker.call({
521
+ method,
522
+ args,
523
+ resolve,
524
+ reject,
525
+ retries: 0
526
+ });
527
+ }));
528
+ }
529
+
530
+ promises.push(this.localWorker[method](this.workerApi, ...args));
531
+ await Promise.all(promises);
532
+ }
533
+
534
+ async takeHeapSnapshot() {
535
+ let snapshotId = getTimeId();
536
+
537
+ try {
538
+ let snapshotPaths = await Promise.all([...this.workers.values()].map(worker => new Promise((resolve, reject) => {
539
+ worker.call({
540
+ method: 'takeHeapSnapshot',
541
+ args: [snapshotId],
542
+ resolve,
543
+ reject,
544
+ retries: 0,
545
+ skipReadyCheck: true
546
+ });
547
+ })));
548
+
549
+ _logger().default.info({
550
+ origin: '@parcel/workers',
551
+ message: (0, _diagnostic().md)`Wrote heap snapshots to the following paths:\n${snapshotPaths.join('\n')}`
552
+ });
553
+ } catch {
554
+ _logger().default.error({
555
+ origin: '@parcel/workers',
556
+ message: 'Unable to take heap snapshots. Note: requires Node 11.13.0+'
557
+ });
558
+ }
559
+ }
560
+
464
561
  static getNumWorkers() {
465
- return process.env.PARCEL_WORKERS ? parseInt(process.env.PARCEL_WORKERS, 10) : (0, _cpuCount.default)();
562
+ return process.env.PARCEL_WORKERS ? parseInt(process.env.PARCEL_WORKERS, 10) : Math.ceil((0, _cpuCount.default)() / 2);
466
563
  }
467
564
 
468
565
  static isWorker() {
@@ -470,14 +567,19 @@ class WorkerFarm extends _events.default {
470
567
  }
471
568
 
472
569
  static getWorkerApi() {
473
- (0, _assert.default)(_childState.child != null, 'WorkerFarm.getWorkerApi can only be called within workers');
570
+ (0, _assert().default)(_childState.child != null, 'WorkerFarm.getWorkerApi can only be called within workers');
474
571
  return _childState.child.workerApi;
475
572
  }
476
573
 
477
574
  static getConcurrentCallsPerWorker() {
478
- return parseInt(process.env.PARCEL_MAX_CONCURRENT_CALLS, 10) || 5;
575
+ return parseInt(process.env.PARCEL_MAX_CONCURRENT_CALLS, 10) || 30;
479
576
  }
480
577
 
481
578
  }
482
579
 
483
- exports.default = WorkerFarm;
580
+ exports.default = WorkerFarm;
581
+
582
+ function getTimeId() {
583
+ let now = new Date();
584
+ return String(now.getFullYear()) + String(now.getMonth() + 1).padStart(2, '0') + String(now.getDate()).padStart(2, '0') + '-' + String(now.getHours()).padStart(2, '0') + String(now.getMinutes()).padStart(2, '0') + String(now.getSeconds()).padStart(2, '0');
585
+ }
package/lib/backend.js CHANGED
@@ -7,6 +7,12 @@ exports.detectBackend = detectBackend;
7
7
  exports.getWorkerBackend = getWorkerBackend;
8
8
 
9
9
  function detectBackend() {
10
+ switch (process.env.PARCEL_WORKER_BACKEND) {
11
+ case 'threads':
12
+ case 'process':
13
+ return process.env.PARCEL_WORKER_BACKEND;
14
+ }
15
+
10
16
  try {
11
17
  require('worker_threads');
12
18
 
package/lib/bus.js CHANGED
@@ -5,13 +5,21 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _events = _interopRequireDefault(require("events"));
8
+ function _events() {
9
+ const data = _interopRequireDefault(require("events"));
10
+
11
+ _events = function () {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
9
17
 
10
18
  var _childState = require("./childState");
11
19
 
12
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
21
 
14
- class Bus extends _events.default {
22
+ class Bus extends _events().default {
15
23
  emit(event, ...args) {
16
24
  if (_childState.child) {
17
25
  _childState.child.workerApi.callMaster({