@parcel/workers 2.8.3 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,66 +4,46 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  function _worker_threads() {
9
8
  const data = require("worker_threads");
10
-
11
9
  _worker_threads = function () {
12
10
  return data;
13
11
  };
14
-
15
12
  return data;
16
13
  }
17
-
18
14
  function _nullthrows() {
19
15
  const data = _interopRequireDefault(require("nullthrows"));
20
-
21
16
  _nullthrows = function () {
22
17
  return data;
23
18
  };
24
-
25
19
  return data;
26
20
  }
27
-
28
21
  var _childState = require("../childState");
29
-
30
22
  var _child = require("../child");
31
-
32
23
  function _core() {
33
24
  const data = require("@parcel/core");
34
-
35
25
  _core = function () {
36
26
  return data;
37
27
  };
38
-
39
28
  return data;
40
29
  }
41
-
42
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
-
44
31
  class ThreadsChild {
45
32
  constructor(onMessage, onExit) {
46
33
  if (_worker_threads().isMainThread || !_worker_threads().parentPort) {
47
34
  throw new Error('Only create ThreadsChild instances in a worker!');
48
35
  }
49
-
50
36
  this.onMessage = onMessage;
51
37
  this.onExit = onExit;
52
-
53
38
  _worker_threads().parentPort.on('message', data => this.handleMessage(data));
54
-
55
39
  _worker_threads().parentPort.on('close', this.onExit);
56
40
  }
57
-
58
41
  handleMessage(data) {
59
42
  this.onMessage((0, _core().restoreDeserializedObject)(data));
60
43
  }
61
-
62
44
  send(data) {
63
45
  (0, _nullthrows().default)(_worker_threads().parentPort).postMessage((0, _core().prepareForSerialization)(data));
64
46
  }
65
-
66
47
  }
67
-
68
48
  exports.default = ThreadsChild;
69
49
  (0, _childState.setChild)(new _child.Child(ThreadsChild));
@@ -4,41 +4,29 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  function _worker_threads() {
9
8
  const data = require("worker_threads");
10
-
11
9
  _worker_threads = function () {
12
10
  return data;
13
11
  };
14
-
15
12
  return data;
16
13
  }
17
-
18
14
  function _path() {
19
15
  const data = _interopRequireDefault(require("path"));
20
-
21
16
  _path = function () {
22
17
  return data;
23
18
  };
24
-
25
19
  return data;
26
20
  }
27
-
28
21
  function _core() {
29
22
  const data = require("@parcel/core");
30
-
31
23
  _core = function () {
32
24
  return data;
33
25
  };
34
-
35
26
  return data;
36
27
  }
37
-
38
28
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
-
40
29
  const WORKER_PATH = _path().default.join(__dirname, 'ThreadsChild.js');
41
-
42
30
  class ThreadsWorker {
43
31
  constructor(execArgv, onMessage, onError, onExit) {
44
32
  this.execArgv = execArgv;
@@ -46,7 +34,6 @@ class ThreadsWorker {
46
34
  this.onError = onError;
47
35
  this.onExit = onExit;
48
36
  }
49
-
50
37
  start() {
51
38
  this.worker = new (_worker_threads().Worker)(WORKER_PATH, {
52
39
  execArgv: this.execArgv,
@@ -59,21 +46,16 @@ class ThreadsWorker {
59
46
  this.worker.on('online', resolve);
60
47
  });
61
48
  }
62
-
63
49
  stop() {
64
50
  // In node 12, this returns a promise, but previously it accepted a callback
65
51
  // TODO: Pass a callback in earlier versions of Node
66
52
  return Promise.resolve(this.worker.terminate());
67
53
  }
68
-
69
54
  handleMessage(data) {
70
55
  this.onMessage((0, _core().restoreDeserializedObject)(data));
71
56
  }
72
-
73
57
  send(data) {
74
58
  this.worker.postMessage((0, _core().prepareForSerialization)(data));
75
59
  }
76
-
77
60
  }
78
-
79
61
  exports.default = ThreadsWorker;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parcel/workers",
3
- "version": "2.8.3",
3
+ "version": "2.9.0",
4
4
  "description": "Blazing fast, zero configuration web application bundler",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -21,20 +21,20 @@
21
21
  "node": ">= 12.0.0"
22
22
  },
23
23
  "dependencies": {
24
- "@parcel/diagnostic": "2.8.3",
25
- "@parcel/logger": "2.8.3",
26
- "@parcel/types": "2.8.3",
27
- "@parcel/utils": "2.8.3",
28
- "chrome-trace-event": "^1.0.2",
24
+ "@parcel/diagnostic": "2.9.0",
25
+ "@parcel/logger": "2.9.0",
26
+ "@parcel/profiler": "2.9.0",
27
+ "@parcel/types": "2.9.0",
28
+ "@parcel/utils": "2.9.0",
29
29
  "nullthrows": "^1.1.1"
30
30
  },
31
31
  "peerDependencies": {
32
- "@parcel/core": "^2.8.3"
32
+ "@parcel/core": "^2.9.0"
33
33
  },
34
34
  "browser": {
35
35
  "./src/cpuCount.js": false,
36
36
  "./src/process/ProcessWorker.js": false,
37
37
  "./src/threads/ThreadsWorker.js": false
38
38
  },
39
- "gitHead": "349a6caf40ec8abb6a49fcae0765f8f8deb2073d"
39
+ "gitHead": "dd9435be8afed35c5ffc161cf4b586fd6c78fc1f"
40
40
  }
package/src/Worker.js CHANGED
@@ -23,6 +23,7 @@ type WorkerOpts = {|
23
23
  forcedKillTime: number,
24
24
  backend: BackendType,
25
25
  shouldPatchConsole?: boolean,
26
+ shouldTrace?: boolean,
26
27
  sharedReferences: $ReadOnlyMap<SharedReference, mixed>,
27
28
  |};
28
29
 
@@ -108,6 +109,7 @@ export default class Worker extends EventEmitter {
108
109
  forkModule,
109
110
  {
110
111
  shouldPatchConsole: !!this.options.shouldPatchConsole,
112
+ shouldTrace: !!this.options.shouldTrace,
111
113
  },
112
114
  ],
113
115
  retries: 0,
package/src/WorkerFarm.js CHANGED
@@ -26,8 +26,7 @@ import cpuCount from './cpuCount';
26
26
  import Handle from './Handle';
27
27
  import {child} from './childState';
28
28
  import {detectBackend} from './backend';
29
- import Profiler from './Profiler';
30
- import Trace from './Trace';
29
+ import {SamplingProfiler, Trace} from '@parcel/profiler';
31
30
  import fs from 'fs';
32
31
  import logger from '@parcel/logger';
33
32
 
@@ -44,6 +43,7 @@ export type FarmOptions = {|
44
43
  workerPath?: FilePath,
45
44
  backend: BackendType,
46
45
  shouldPatchConsole?: boolean,
46
+ shouldTrace?: boolean,
47
47
  |};
48
48
 
49
49
  type WorkerModule = {|
@@ -60,6 +60,8 @@ export type WorkerApi = {|
60
60
 
61
61
  export {Handle};
62
62
 
63
+ const DEFAULT_MAX_CONCURRENT_CALLS: number = 30;
64
+
63
65
  /**
64
66
  * workerPath should always be defined inside farmOptions
65
67
  */
@@ -77,13 +79,15 @@ export default class WorkerFarm extends EventEmitter {
77
79
  sharedReferences: Map<SharedReference, mixed> = new Map();
78
80
  sharedReferencesByValue: Map<mixed, SharedReference> = new Map();
79
81
  serializedSharedReferences: Map<SharedReference, ?ArrayBuffer> = new Map();
80
- profiler: ?Profiler;
82
+ profiler: ?SamplingProfiler;
81
83
 
82
84
  constructor(farmOptions: $Shape<FarmOptions> = {}) {
83
85
  super();
84
86
  this.options = {
85
87
  maxConcurrentWorkers: WorkerFarm.getNumWorkers(),
86
- maxConcurrentCallsPerWorker: WorkerFarm.getConcurrentCallsPerWorker(),
88
+ maxConcurrentCallsPerWorker: WorkerFarm.getConcurrentCallsPerWorker(
89
+ farmOptions.shouldTrace ? 1 : DEFAULT_MAX_CONCURRENT_CALLS,
90
+ ),
87
91
  forcedKillTime: 500,
88
92
  warmWorkers: false,
89
93
  useLocalWorker: true, // TODO: setting this to false makes some tests fail, figure out why
@@ -192,6 +196,10 @@ export default class WorkerFarm extends EventEmitter {
192
196
  }
193
197
 
194
198
  createHandle(method: string, useMainThread: boolean = false): HandleFunction {
199
+ if (!this.options.useLocalWorker) {
200
+ useMainThread = false;
201
+ }
202
+
195
203
  return async (...args) => {
196
204
  // Child process workers are slow to start (~600ms).
197
205
  // While we're waiting, just run on the main thread.
@@ -235,6 +243,7 @@ export default class WorkerFarm extends EventEmitter {
235
243
  forcedKillTime: this.options.forcedKillTime,
236
244
  backend: this.options.backend,
237
245
  shouldPatchConsole: this.options.shouldPatchConsole,
246
+ shouldTrace: this.options.shouldTrace,
238
247
  sharedReferences: this.sharedReferences,
239
248
  });
240
249
 
@@ -512,7 +521,7 @@ export default class WorkerFarm extends EventEmitter {
512
521
  );
513
522
  }
514
523
 
515
- this.profiler = new Profiler();
524
+ this.profiler = new SamplingProfiler();
516
525
 
517
526
  promises.push(this.profiler.startProfiling());
518
527
  await Promise.all(promises);
@@ -643,8 +652,12 @@ export default class WorkerFarm extends EventEmitter {
643
652
  return child.workerApi;
644
653
  }
645
654
 
646
- static getConcurrentCallsPerWorker(): number {
647
- return parseInt(process.env.PARCEL_MAX_CONCURRENT_CALLS, 10) || 30;
655
+ static getConcurrentCallsPerWorker(
656
+ defaultValue?: number = DEFAULT_MAX_CONCURRENT_CALLS,
657
+ ): number {
658
+ return (
659
+ parseInt(process.env.PARCEL_MAX_CONCURRENT_CALLS, 10) || defaultValue
660
+ );
648
661
  }
649
662
  }
650
663
 
package/src/child.js CHANGED
@@ -18,7 +18,7 @@ import Logger, {patchConsole, unpatchConsole} from '@parcel/logger';
18
18
  import ThrowableDiagnostic, {anyToDiagnostic} from '@parcel/diagnostic';
19
19
  import {deserialize} from '@parcel/core';
20
20
  import bus from './bus';
21
- import Profiler from './Profiler';
21
+ import {SamplingProfiler, tracer} from '@parcel/profiler';
22
22
  import _Handle from './Handle';
23
23
 
24
24
  // The import of './Handle' should really be imported eagerly (with @babel/plugin-transform-modules-commonjs's lazy mode).
@@ -37,8 +37,9 @@ export class Child {
37
37
  responseId: number = 0;
38
38
  responseQueue: Map<number, ChildCall> = new Map();
39
39
  loggerDisposable: IDisposable;
40
+ tracerDisposable: IDisposable;
40
41
  child: ChildImpl;
41
- profiler: ?Profiler;
42
+ profiler: ?SamplingProfiler;
42
43
  handles: Map<number, Handle> = new Map();
43
44
  sharedReferences: Map<SharedReference, mixed> = new Map();
44
45
  sharedReferencesByValue: Map<mixed, SharedReference> = new Map();
@@ -56,6 +57,10 @@ export class Child {
56
57
  this.loggerDisposable = Logger.onLog(event => {
57
58
  bus.emit('logEvent', event);
58
59
  });
60
+ // .. and do the same for trace events
61
+ this.tracerDisposable = tracer.onTrace(event => {
62
+ bus.emit('traceEvent', event);
63
+ });
59
64
  }
60
65
 
61
66
  workerApi: {|
@@ -141,12 +146,16 @@ export class Child {
141
146
  unpatchConsole();
142
147
  }
143
148
 
149
+ if (childOptions.shouldTrace) {
150
+ tracer.enable();
151
+ }
152
+
144
153
  result = responseFromContent(await this.childInit(moduleName, child));
145
154
  } catch (e) {
146
155
  result = errorResponseFromError(e);
147
156
  }
148
157
  } else if (method === 'startProfile') {
149
- this.profiler = new Profiler();
158
+ this.profiler = new SamplingProfiler();
150
159
  try {
151
160
  result = responseFromContent(await this.profiler.startProfiling());
152
161
  } catch (e) {
@@ -289,6 +298,7 @@ export class Child {
289
298
 
290
299
  handleEnd(): void {
291
300
  this.loggerDisposable.dispose();
301
+ this.tracerDisposable.dispose();
292
302
  }
293
303
 
294
304
  createReverseHandle(fn: (...args: Array<any>) => mixed): Handle {
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,6 +30,11 @@ 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;
package/lib/Profiler.js DELETED
@@ -1,80 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- function _assert() {
9
- const data = _interopRequireDefault(require("assert"));
10
-
11
- _assert = function () {
12
- return data;
13
- };
14
-
15
- return data;
16
- }
17
-
18
- function _diagnostic() {
19
- const data = _interopRequireDefault(require("@parcel/diagnostic"));
20
-
21
- _diagnostic = function () {
22
- return data;
23
- };
24
-
25
- return data;
26
- }
27
-
28
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
-
30
- class Profiler {
31
- startProfiling() {
32
- let inspector;
33
-
34
- try {
35
- inspector = require('inspector');
36
- } catch (err) {
37
- throw new (_diagnostic().default)({
38
- diagnostic: {
39
- message: `The inspector module isn't available`,
40
- origin: '@parcel/workers',
41
- hints: ['Disable build profiling']
42
- }
43
- });
44
- }
45
-
46
- this.session = new inspector.Session();
47
- this.session.connect();
48
- return Promise.all([this.sendCommand('Profiler.setSamplingInterval', {
49
- interval: 100
50
- }), this.sendCommand('Profiler.enable'), this.sendCommand('Profiler.start')]);
51
- }
52
-
53
- sendCommand(method, params) {
54
- (0, _assert().default)(this.session != null);
55
- return new Promise((resolve, reject) => {
56
- this.session.post(method, params, (err, params) => {
57
- if (err == null) {
58
- resolve(params);
59
- } else {
60
- reject(err);
61
- }
62
- });
63
- });
64
- }
65
-
66
- destroy() {
67
- if (this.session != null) {
68
- this.session.disconnect();
69
- }
70
- }
71
-
72
- async stopProfiling() {
73
- let res = await this.sendCommand('Profiler.stop');
74
- this.destroy();
75
- return res.profile;
76
- }
77
-
78
- }
79
-
80
- exports.default = Profiler;
package/lib/Trace.js DELETED
@@ -1,131 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- function _chromeTraceEvent() {
9
- const data = require("chrome-trace-event");
10
-
11
- _chromeTraceEvent = function () {
12
- return data;
13
- };
14
-
15
- return data;
16
- }
17
-
18
- class Trace {
19
- constructor() {
20
- this.tracer = new (_chromeTraceEvent().Tracer)();
21
- this.tid = 0;
22
- this.eventId = 0;
23
- }
24
-
25
- getEventId() {
26
- return this.eventId++;
27
- }
28
-
29
- init(ts) {
30
- this.tracer.instantEvent({
31
- name: 'TracingStartedInPage',
32
- id: this.getEventId(),
33
- ts,
34
- cat: ['disabled-by-default-devtools.timeline'],
35
- args: {
36
- data: {
37
- sessionId: '-1',
38
- page: '0xfff',
39
- frames: [{
40
- frame: '0xfff',
41
- url: 'parcel',
42
- name: ''
43
- }]
44
- }
45
- }
46
- });
47
- this.tracer.instantEvent({
48
- name: 'TracingStartedInBrowser',
49
- id: this.getEventId(),
50
- ts,
51
- cat: ['disabled-by-default-devtools.timeline'],
52
- args: {
53
- data: {
54
- sessionId: '-1'
55
- }
56
- }
57
- });
58
- }
59
-
60
- addCPUProfile(name, profile) {
61
- if (this.eventId === 0) {
62
- this.init(profile.startTime);
63
- }
64
-
65
- const trace = this.tracer;
66
- const tid = this.tid;
67
- this.tid++;
68
- const cpuStartTime = profile.startTime;
69
- const cpuEndTime = profile.endTime;
70
- trace.instantEvent({
71
- tid,
72
- id: this.getEventId(),
73
- cat: ['toplevel'],
74
- name: 'TaskQueueManager::ProcessTaskFromWorkQueue',
75
- args: {
76
- src_file: '../../ipc/ipc_moji_bootstrap.cc',
77
- src_func: 'Accept'
78
- },
79
- ts: cpuStartTime
80
- });
81
- trace.completeEvent({
82
- tid,
83
- name: 'EvaluateScript',
84
- id: this.getEventId(),
85
- cat: ['devtools.timeline'],
86
- ts: cpuStartTime,
87
- dur: cpuEndTime - cpuStartTime,
88
- args: {
89
- data: {
90
- url: 'parcel',
91
- lineNumber: 1,
92
- columnNumber: 1,
93
- frame: '0xFFF'
94
- }
95
- }
96
- });
97
- trace.instantEvent({
98
- tid,
99
- ts: 0,
100
- ph: 'M',
101
- cat: ['__metadata'],
102
- name: 'thread_name',
103
- args: {
104
- name
105
- }
106
- });
107
- trace.instantEvent({
108
- tid,
109
- name: 'CpuProfile',
110
- id: this.getEventId(),
111
- cat: ['disabled-by-default-devtools.timeline'],
112
- ts: cpuEndTime,
113
- args: {
114
- data: {
115
- cpuProfile: profile
116
- }
117
- }
118
- });
119
- }
120
-
121
- pipe(writable) {
122
- return this.tracer.pipe(writable);
123
- }
124
-
125
- flush() {
126
- this.tracer.push(null);
127
- }
128
-
129
- }
130
-
131
- exports.default = Trace;
package/src/Profiler.js DELETED
@@ -1,93 +0,0 @@
1
- // @flow
2
- import type {Session} from 'inspector';
3
- import invariant from 'assert';
4
- import ThrowableDiagnostic from '@parcel/diagnostic';
5
-
6
- // https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-Profile
7
- export type Profile = {|
8
- nodes: Array<ProfileNode>,
9
- startTime: number,
10
- endTime: number,
11
- samples?: Array<number>,
12
- timeDeltas?: Array<number>,
13
- |};
14
-
15
- // https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ProfileNode
16
- type ProfileNode = {|
17
- id: number,
18
- callFrame: CallFrame,
19
- hitCount?: number,
20
- children?: Array<number>,
21
- deoptReason?: string,
22
- positionTicks?: PositionTickInfo,
23
- |};
24
-
25
- // https://chromedevtools.github.io/devtools-protocol/tot/Runtime#type-CallFrame
26
- type CallFrame = {|
27
- functionName: string,
28
- scriptId: string,
29
- url: string,
30
- lineNumber: string,
31
- columnNumber: string,
32
- |};
33
-
34
- // https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-PositionTickInfo
35
- type PositionTickInfo = {|
36
- line: number,
37
- ticks: number,
38
- |};
39
-
40
- export default class Profiler {
41
- session: Session;
42
-
43
- startProfiling(): Promise<mixed> {
44
- let inspector;
45
- try {
46
- inspector = require('inspector');
47
- } catch (err) {
48
- throw new ThrowableDiagnostic({
49
- diagnostic: {
50
- message: `The inspector module isn't available`,
51
- origin: '@parcel/workers',
52
- hints: ['Disable build profiling'],
53
- },
54
- });
55
- }
56
-
57
- this.session = new inspector.Session();
58
- this.session.connect();
59
-
60
- return Promise.all([
61
- this.sendCommand('Profiler.setSamplingInterval', {
62
- interval: 100,
63
- }),
64
- this.sendCommand('Profiler.enable'),
65
- this.sendCommand('Profiler.start'),
66
- ]);
67
- }
68
-
69
- sendCommand(method: string, params: mixed): Promise<{profile: Profile, ...}> {
70
- invariant(this.session != null);
71
- return new Promise((resolve, reject) => {
72
- this.session.post(method, params, (err, params) => {
73
- if (err == null) {
74
- resolve(params);
75
- } else {
76
- reject(err);
77
- }
78
- });
79
- });
80
- }
81
-
82
- destroy() {
83
- if (this.session != null) {
84
- this.session.disconnect();
85
- }
86
- }
87
-
88
- async stopProfiling(): Promise<Profile> {
89
- let res = await this.sendCommand('Profiler.stop');
90
- this.destroy();
91
- return res.profile;
92
- }
93
- }