Skip to content

Commit 68206cd

Browse files
author
Daniel Del Core
committed
Worker migration to worker_threads
1 parent 2f41e44 commit 68206cd

File tree

2 files changed

+49
-61
lines changed

2 files changed

+49
-61
lines changed

packages/core/lib/Worker.js

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,28 @@
1-
/* eslint-disable @typescript-eslint/no-var-requires */
2-
'use strict';
3-
4-
const path = require('path');
5-
const { EventEmitter } = require('events');
6-
const async = require('neo-async');
7-
const fs = require('graceful-fs');
8-
const writeFileAtomic = require('write-file-atomic');
9-
const { DEFAULT_EXTENSIONS } = require('@babel/core');
10-
11-
const getParser = require('jscodeshift/src/getParser');
12-
const jscodeshift = require('jscodeshift/src/core');
13-
14-
let presetEnv;
15-
try {
16-
presetEnv = require('@babel/preset-env');
17-
} catch (_) {}
18-
19-
let emitter;
20-
let finish;
21-
let notify;
1+
import path from 'path';
2+
import async from 'neo-async';
3+
import fs from 'graceful-fs';
4+
import writeFileAtomic from 'write-file-atomic';
5+
import { fileURLToPath } from 'url';
6+
import { register } from 'tsx/esm/api';
7+
8+
import getParser from 'jscodeshift/src/getParser.js';
9+
import jscodeshift from 'jscodeshift/src/core.js';
10+
import { workerData, isMainThread, parentPort } from 'worker_threads';
11+
12+
/**
13+
* Register the TSX plugin to allow import TS(X) files.
14+
*/
15+
register();
16+
2217
let transform;
2318
let parserFromTransform;
2419

25-
if (module.parent) {
26-
emitter = new EventEmitter();
27-
// @ts-expect-error
28-
emitter.send = data => run(data);
29-
finish = () => emitter.emit('disconnect');
30-
notify = data => emitter.emit('message', data);
31-
32-
module.exports = args => {
33-
setup(args[0], args[1]);
34-
return emitter;
35-
};
36-
} else {
37-
finish = () => setImmediate(() => process.disconnect());
38-
notify = data => process.send(data);
39-
process.on('message', data => run(data));
40-
setup(process.argv[2], process.argv[3]);
20+
// Get the __filename and __dirname equivalents for ESM
21+
const __filename = fileURLToPath(import.meta.url);
22+
23+
if (!isMainThread) {
24+
await setup(workerData.entrypointPath);
25+
parentPort.on('message', data => run(data));
4126
}
4227

4328
function prepareJscodeshift(options) {
@@ -102,12 +87,12 @@ async function setup(entryPath) {
10287

10388
function updateStatus(status, file, msg) {
10489
msg = msg ? file + ' ' + msg : file;
105-
notify({ action: 'status', status, msg });
90+
parentPort.postMessage({ action: 'status', status, msg });
10691
}
10792

10893
function stats(name, quantity) {
10994
quantity = typeof quantity !== 'number' ? 1 : quantity;
110-
notify({ action: 'update', name: name, quantity: quantity });
95+
parentPort.postMessage({ action: 'update', name: name, quantity: quantity });
11196
}
11297

11398
function trimStackTrace(trace) {
@@ -130,9 +115,10 @@ function run(data) {
130115
const options = data.options || {};
131116

132117
if (!files.length) {
133-
finish();
118+
parentPort.close();
134119
return;
135120
}
121+
136122
async.each(
137123
files,
138124
function (file, callback) {
@@ -153,7 +139,8 @@ function run(data) {
153139
jscodeshift: jscodeshift,
154140
// eslint-disable-next-line @typescript-eslint/no-empty-function
155141
stats: options.dry ? stats : () => {},
156-
report: msg => notify({ action: 'report', file, msg }),
142+
report: msg =>
143+
parentPort.postMessage({ action: 'report', file, msg }),
157144
},
158145
options,
159146
);
@@ -196,7 +183,7 @@ function run(data) {
196183
if (err) {
197184
updateStatus('error', '', 'This should never be shown!');
198185
}
199-
notify({ action: 'free' });
186+
parentPort.postMessage({ action: 'free' });
200187
},
201188
);
202189
}

packages/core/src/runner.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import child_process from 'child_process';
1+
import { Worker } from 'worker_threads';
22
import chalk from 'chalk';
33
import fs from 'graceful-fs';
44
import path from 'path';
55
import os from 'os';
6-
// @ts-expect-error
7-
import ignores from 'jscodeshift/src/ignoreFiles';
86

9-
import { Message, Flags, Statuses } from './types';
7+
import { Message, Flags, Statuses } from './types.js';
8+
9+
// @ts-expect-error
10+
const ignores = await import('jscodeshift/src/ignoreFiles.js');
11+
// @ts-expect-error
12+
const __dirname = import.meta.dirname;
1013

1114
type FileCounters = Record<Statuses, number>;
1215
type Stats = Record<string, number>;
@@ -230,25 +233,23 @@ export function run(
230233
}
231234
}
232235

233-
const args = [entrypointPath, options.babel ? 'babel' : 'no-babel'];
234-
235-
const workers = [];
236+
const workers: Worker[] = [];
236237

237238
for (let i = 0; i < processes; i++) {
238239
workers.push(
239-
options.runInBand
240-
? // eslint-disable-next-line @typescript-eslint/no-var-requires
241-
require('../lib/Worker')(args)
242-
: child_process.fork(
243-
path.join(__dirname, '..', 'lib', 'Worker.js'),
244-
args,
245-
),
240+
new Worker(path.join(__dirname, '..', 'lib', 'Worker.js'), {
241+
workerData: {
242+
entrypointPath,
243+
babel: options.babel ? 'babel' : 'no-babel',
244+
},
245+
}),
246246
);
247247
}
248248

249-
return workers.map(child => {
250-
child.send({ files: next(), options });
251-
child.on('message', (message: Message) => {
249+
return workers.map(worker => {
250+
worker.postMessage({ files: next(), options });
251+
worker.on('error', (message: Message) => console.error(message));
252+
worker.on('message', (message: Message) => {
252253
switch (message.action) {
253254
case 'status':
254255
fileCounters[message.status] += 1;
@@ -261,7 +262,7 @@ export function run(
261262
statsCounter[message.name] += message.quantity;
262263
break;
263264
case 'free':
264-
child.send({ files: next(), options });
265+
worker.postMessage({ files: next(), options });
265266
break;
266267
case 'report':
267268
bufferedWrite(
@@ -274,7 +275,7 @@ export function run(
274275
break;
275276
}
276277
});
277-
return new Promise(resolve => child.on('disconnect', resolve));
278+
return new Promise(resolve => worker.on('close', resolve));
278279
});
279280
})
280281
.then(pendingWorkers =>

0 commit comments

Comments
 (0)