@parcel/workers 2.0.0-nightly.144 → 2.0.0-nightly.1441

Sign up to get free protection for your applications and to get access to all the features.
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;