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