@parcel/workers 2.0.0-nightly.92 → 2.0.1

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,80 +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, "profiler", void 0);
83
-
84
- _defineProperty(this, "workerApi", {
85
- callMaster: async (request, awaitResponse = true) => {
86
- // $FlowFixMe
87
- let result = await this.processRequest(_objectSpread({}, request, {
88
- awaitResponse
89
- }));
90
- return (0, _core.deserialize)((0, _core.serialize)(result));
91
- },
92
- createReverseHandle: fn => this.createReverseHandle(fn),
93
- callChild: (childId, request) => new Promise((resolve, reject) => {
94
- (0, _nullthrows.default)(this.workers.get(childId)).call(_objectSpread({}, request, {
95
- resolve,
96
- reject,
97
- retries: 0
98
- }));
99
- }),
100
- getSharedReference: ref => this.sharedReferences.get(ref)
101
- });
102
-
103
- this.options = _objectSpread({
120
+ this.options = {
104
121
  maxConcurrentWorkers: WorkerFarm.getNumWorkers(),
105
122
  maxConcurrentCallsPerWorker: WorkerFarm.getConcurrentCallsPerWorker(),
106
123
  forcedKillTime: 500,
107
124
  warmWorkers: false,
108
125
  useLocalWorker: true,
109
126
  // TODO: setting this to false makes some tests fail, figure out why
110
- backend: (0, _backend.detectBackend)()
111
- }, farmOptions);
127
+ backend: (0, _backend.detectBackend)(),
128
+ ...farmOptions
129
+ };
112
130
 
113
131
  if (!this.options.workerPath) {
114
132
  throw new Error('Please provide a worker path!');
@@ -116,10 +134,35 @@ class WorkerFarm extends _events.default {
116
134
 
117
135
 
118
136
  this.localWorker = require(this.options.workerPath);
137
+ this.localWorkerInit = this.localWorker.childInit != null ? this.localWorker.childInit() : null;
119
138
  this.run = this.createHandle('run');
120
139
  this.startMaxWorkers();
121
140
  }
122
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
+
123
166
  warmupWorker(method, args) {
124
167
  // Workers are already stopping
125
168
  if (this.ending) {
@@ -147,7 +190,7 @@ class WorkerFarm extends _events.default {
147
190
  }
148
191
 
149
192
  createHandle(method) {
150
- return (...args) => {
193
+ return async (...args) => {
151
194
  // Child process workers are slow to start (~600ms).
152
195
  // While we're waiting, just run on the main thread.
153
196
  // This significantly speeds up startup time.
@@ -158,7 +201,13 @@ class WorkerFarm extends _events.default {
158
201
  this.warmupWorker(method, args);
159
202
  }
160
203
 
161
- 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
+
162
211
  return this.localWorker[method](this.workerApi, ...processedArgs);
163
212
  }
164
213
  };
@@ -168,6 +217,8 @@ class WorkerFarm extends _events.default {
168
217
  // Handle ipc errors
169
218
  if (error.code === 'ERR_IPC_CHANNEL_CLOSED') {
170
219
  return this.stopWorker(worker);
220
+ } else {
221
+ _logger().default.error(error, '@parcel/workers');
171
222
  }
172
223
  }
173
224
 
@@ -175,9 +226,10 @@ class WorkerFarm extends _events.default {
175
226
  let worker = new _Worker.default({
176
227
  forcedKillTime: this.options.forcedKillTime,
177
228
  backend: this.options.backend,
178
- patchConsole: this.options.patchConsole
229
+ shouldPatchConsole: this.options.shouldPatchConsole,
230
+ sharedReferences: this.sharedReferences
179
231
  });
180
- worker.fork((0, _nullthrows.default)(this.options.workerPath));
232
+ worker.fork((0, _nullthrows().default)(this.options.workerPath));
181
233
  worker.on('request', data => this.processRequest(data, worker));
182
234
  worker.on('ready', () => this.processQueue());
183
235
  worker.on('response', () => this.processQueue());
@@ -212,7 +264,9 @@ class WorkerFarm extends _events.default {
212
264
  this.startChild();
213
265
  }
214
266
 
215
- 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) {
216
270
  if (!this.callQueue.length) {
217
271
  break;
218
272
  }
@@ -239,7 +293,9 @@ class WorkerFarm extends _events.default {
239
293
  let mod;
240
294
 
241
295
  if (handleId != null) {
242
- 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);
243
299
  } else if (location) {
244
300
  // $FlowFixMe this must be dynamic
245
301
  mod = require(location);
@@ -258,27 +314,26 @@ class WorkerFarm extends _events.default {
258
314
  idx,
259
315
  type: 'response',
260
316
  contentType: 'error',
261
- content: (0, _diagnostic.anyToDiagnostic)(e)
317
+ content: (0, _diagnostic().anyToDiagnostic)(e)
262
318
  });
263
319
 
264
320
  let result;
265
321
 
266
322
  if (method == null) {
267
323
  try {
268
- result = responseFromContent((await mod(...args)));
324
+ result = responseFromContent(await mod(...args));
269
325
  } catch (e) {
270
326
  result = errorResponseFromError(e);
271
327
  }
272
328
  } else {
273
329
  // ESModule default interop
274
- // $FlowFixMe
275
330
  if (mod.__esModule && !mod[method] && mod.default) {
276
331
  mod = mod.default;
277
332
  }
278
333
 
279
334
  try {
280
335
  // $FlowFixMe
281
- result = responseFromContent((await mod[method](...args)));
336
+ result = responseFromContent(await mod[method](...args));
282
337
  } catch (e) {
283
338
  result = errorResponseFromError(e);
284
339
  }
@@ -289,7 +344,7 @@ class WorkerFarm extends _events.default {
289
344
  worker.send(result);
290
345
  } else {
291
346
  if (result.contentType === 'error') {
292
- throw new _diagnostic.default({
347
+ throw new (_diagnostic().default)({
293
348
  diagnostic: result.content
294
349
  });
295
350
  }
@@ -318,6 +373,7 @@ class WorkerFarm extends _events.default {
318
373
 
319
374
  async end() {
320
375
  this.ending = true;
376
+ await Promise.all(Array.from(this.workers.values()).map(worker => this.stopWorker(worker)));
321
377
 
322
378
  for (let handle of this.handles.values()) {
323
379
  handle.dispose();
@@ -325,7 +381,7 @@ class WorkerFarm extends _events.default {
325
381
 
326
382
  this.handles = new Map();
327
383
  this.sharedReferences = new Map();
328
- await Promise.all(Array.from(this.workers.values()).map(worker => this.stopWorker(worker)));
384
+ this.sharedReferencesByValue = new Map();
329
385
  this.ending = false;
330
386
  }
331
387
 
@@ -346,28 +402,25 @@ class WorkerFarm extends _events.default {
346
402
 
347
403
  createReverseHandle(fn) {
348
404
  let handle = new _Handle.default({
349
- fn,
350
- workerApi: this.workerApi
405
+ fn
351
406
  });
352
407
  this.handles.set(handle.id, handle);
353
408
  return handle;
354
409
  }
355
410
 
356
- async createSharedReference(value) {
411
+ async createSharedReference(value, // An optional, pre-serialized representation of the value to be used
412
+ // in its place.
413
+ buffer) {
357
414
  let ref = referenceId++;
358
415
  this.sharedReferences.set(ref, value);
416
+ this.sharedReferencesByValue.set(value, ref);
417
+ let toSend = buffer ? buffer.buffer : value;
359
418
  let promises = [];
360
419
 
361
420
  for (let worker of this.workers.values()) {
362
- promises.push(new Promise((resolve, reject) => {
363
- worker.call({
364
- method: 'createSharedReference',
365
- args: [ref, value],
366
- resolve,
367
- reject,
368
- retries: 0
369
- });
370
- }));
421
+ if (worker.ready) {
422
+ promises.push(worker.sendSharedReference(ref, toSend));
423
+ }
371
424
  }
372
425
 
373
426
  await Promise.all(promises);
@@ -375,6 +428,7 @@ class WorkerFarm extends _events.default {
375
428
  ref,
376
429
  dispose: () => {
377
430
  this.sharedReferences.delete(ref);
431
+ this.sharedReferencesByValue.delete(value);
378
432
  let promises = [];
379
433
 
380
434
  for (let worker of this.workers.values()) {
@@ -384,6 +438,7 @@ class WorkerFarm extends _events.default {
384
438
  args: [ref],
385
439
  resolve,
386
440
  reject,
441
+ skipReadyCheck: true,
387
442
  retries: 0
388
443
  });
389
444
  }));
@@ -404,7 +459,8 @@ class WorkerFarm extends _events.default {
404
459
  args: [],
405
460
  resolve,
406
461
  reject,
407
- retries: 0
462
+ retries: 0,
463
+ skipReadyCheck: true
408
464
  });
409
465
  }));
410
466
  }
@@ -430,15 +486,16 @@ class WorkerFarm extends _events.default {
430
486
  args: [],
431
487
  resolve,
432
488
  reject,
433
- retries: 0
489
+ retries: 0,
490
+ skipReadyCheck: true
434
491
  });
435
492
  }));
436
493
  }
437
494
 
438
495
  var profiles = await Promise.all(promises);
439
496
  let trace = new _Trace.default();
440
- let filename = `profile-${profileId++}.trace`;
441
- let stream = trace.pipe(_fs.default.createWriteStream(filename));
497
+ let filename = `profile-${getTimeId()}.trace`;
498
+ let stream = trace.pipe(_fs().default.createWriteStream(filename));
442
499
 
443
500
  for (let profile of profiles) {
444
501
  trace.addCPUProfile(names.shift(), profile);
@@ -449,14 +506,60 @@ class WorkerFarm extends _events.default {
449
506
  stream.once('finish', resolve);
450
507
  });
451
508
 
452
- _logger.default.info({
509
+ _logger().default.info({
453
510
  origin: '@parcel/workers',
454
- message: `Wrote profile to ${filename}`
511
+ message: (0, _diagnostic().md)`Wrote profile to ${filename}`
455
512
  });
456
513
  }
457
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
+
458
561
  static getNumWorkers() {
459
- 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);
460
563
  }
461
564
 
462
565
  static isWorker() {
@@ -464,14 +567,19 @@ class WorkerFarm extends _events.default {
464
567
  }
465
568
 
466
569
  static getWorkerApi() {
467
- (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');
468
571
  return _childState.child.workerApi;
469
572
  }
470
573
 
471
574
  static getConcurrentCallsPerWorker() {
472
- return parseInt(process.env.PARCEL_MAX_CONCURRENT_CALLS, 10) || 5;
575
+ return parseInt(process.env.PARCEL_MAX_CONCURRENT_CALLS, 10) || 30;
473
576
  }
474
577
 
475
578
  }
476
579
 
477
- 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({