Skip to content

Commit

Permalink
feat(jest-worker): factory pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
ayshiff committed Oct 28, 2020
1 parent 286f447 commit cba2c2f
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 44 deletions.
44 changes: 25 additions & 19 deletions packages/jest-haste-map/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,14 +546,16 @@ class HasteMap extends EventEmitter {
if (this._options.retainAllFiles && filePath.includes(NODE_MODULES)) {
if (computeSha1) {
return this._getWorker(workerOptions)
.getSha1({
computeDependencies: this._options.computeDependencies,
computeSha1,
dependencyExtractor: this._options.dependencyExtractor,
filePath,
hasteImplModulePath: this._options.hasteImplModulePath,
rootDir,
})
.then(workerInstance =>
workerInstance.getSha1({
computeDependencies: this._options.computeDependencies,
computeSha1,
dependencyExtractor: this._options.dependencyExtractor,
filePath,
hasteImplModulePath: this._options.hasteImplModulePath,
rootDir,
}),
)
.then(workerReply, workerError);
}

Expand Down Expand Up @@ -622,14 +624,16 @@ class HasteMap extends EventEmitter {
}

return this._getWorker(workerOptions)
.worker({
computeDependencies: this._options.computeDependencies,
computeSha1,
dependencyExtractor: this._options.dependencyExtractor,
filePath,
hasteImplModulePath: this._options.hasteImplModulePath,
rootDir,
})
.then(workerInstance =>
workerInstance.worker({
computeDependencies: this._options.computeDependencies,
computeSha1,
dependencyExtractor: this._options.dependencyExtractor,
filePath,
hasteImplModulePath: this._options.hasteImplModulePath,
rootDir,
}),
)
.then(workerReply, workerError);
}

Expand Down Expand Up @@ -714,17 +718,19 @@ class HasteMap extends EventEmitter {
/**
* Creates workers or parses files and extracts metadata in-process.
*/
private _getWorker(options?: {forceInBand: boolean}): WorkerInterface {
private async _getWorker(options?: {
forceInBand: boolean;
}): Promise<WorkerInterface> {
if (!this._worker) {
if ((options && options.forceInBand) || this._options.maxWorkers <= 1) {
this._worker = {getSha1, worker};
} else {
// @ts-expect-error: assignment of a worker with custom properties.
this._worker = new Worker(require.resolve('./worker'), {
this._worker = (await Worker.create(require.resolve('./worker'), {
exposedMethods: ['getSha1', 'worker'],
maxRetries: 3,
numWorkers: this._options.maxWorkers,
}) as WorkerInterface;
})) as WorkerInterface;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/jest-reporters/src/coverage_reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default class CoverageReporter extends BaseReporter {
if (this._globalConfig.maxWorkers <= 1) {
worker = require('./coverage_worker');
} else {
worker = new Worker(require.resolve('./coverage_worker'), {
worker = await Worker.create(require.resolve('./coverage_worker'), {
exposedMethods: ['worker'],
maxRetries: 2,
numWorkers: this._globalConfig.maxWorkers,
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-runner/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class TestRunner {
}
}

const worker = new Worker(TEST_WORKER_PATH, {
const worker = (await Worker.create(TEST_WORKER_PATH, {
exposedMethods: ['worker'],
forkOptions: {stdio: 'pipe'},
maxRetries: 3,
Expand All @@ -178,7 +178,7 @@ class TestRunner {
serializableResolvers: Array.from(resolvers.values()),
},
],
}) as WorkerInterface;
})) as WorkerInterface;

if (worker.getStdout()) worker.getStdout().pipe(process.stdout);
if (worker.getStderr()) worker.getStderr().pipe(process.stderr);
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-worker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This example covers the minimal usage:
import JestWorker from 'jest-worker';

async function main() {
const worker = new JestWorker(require.resolve('./Worker'));
const worker = await JestWorker.create(require.resolve('./Worker'));
const result = await worker.hello('Alice'); // "Hello, Alice"
}

Expand Down Expand Up @@ -144,7 +144,7 @@ This example covers the standard usage:
import JestWorker from 'jest-worker';

async function main() {
const myWorker = new JestWorker(require.resolve('./Worker'), {
const myWorker = await JestWorker.create(require.resolve('./Worker'), {
exposedMethods: ['foo', 'bar', 'getWorkerId'],
numWorkers: 4,
});
Expand Down Expand Up @@ -188,7 +188,7 @@ This example covers the usage with a `computeWorkerKey` method:
import JestWorker from 'jest-worker';

async function main() {
const myWorker = new JestWorker(require.resolve('./Worker'), {
const myWorker = await JestWorker.create(require.resolve('./Worker'), {
computeWorkerKey: (method, filename) => filename,
});

Expand Down
13 changes: 8 additions & 5 deletions packages/jest-worker/src/__performance_tests__/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,14 @@ function testJestWorker() {
}
}

const farm = new JestWorker(require.resolve('./workers/jest_worker'), {
exposedMethods: [method],
forkOptions: {execArgv: []},
workers: threads,
});
const farm = await JestWorker.create(
require.resolve('./workers/jest_worker'),
{
exposedMethods: [method],
forkOptions: {execArgv: []},
workers: threads,
},
);

farm.getStdout().pipe(process.stdout);
farm.getStderr().pipe(process.stderr);
Expand Down
46 changes: 32 additions & 14 deletions packages/jest-worker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ export default class JestWorker {
this._options = {...options};
this._ending = false;

this._inspectorSession = this.setUpInspector();

const workerPoolOptions: WorkerPoolOptions = {
enableWorkerThreads: this._options.enableWorkerThreads ?? false,
forkOptions: this._options.forkOptions ?? {},
Expand Down Expand Up @@ -111,19 +109,39 @@ export default class JestWorker {
this._bindExposedWorkerMethods(workerPath, this._options);
}

private setUpInspector() {
// Open V8 Inspector
inspector.open();
public static create = async (
workerPath: string,
options?: FarmOptions,
): Promise<JestWorker> => {
const setUpInspector = async () => {
// Open V8 Inspector
inspector.open();

const inspectorUrl = inspector.url();
if (inspectorUrl) {
const session = new inspector.Session();
session.connect();
await new Promise((resolve, reject) => {
session.post('Debugger.enable', (err: Error) => {
if (err === null) {
resolve();
} else {
reject(err);
}
});
});
return session;
}
return undefined;
};

const jestWorker = new JestWorker(workerPath, options);
const inspectorSession = await setUpInspector();

const inspectorUrl = inspector.url();
let session;
if (inspectorUrl !== undefined) {
session = new inspector.Session();
session.connect();
session.post('Debugger.enable');
}
return session;
}
jestWorker._inspectorSession = inspectorSession;

return jestWorker;
};

private _bindExposedWorkerMethods(
workerPath: string,
Expand Down

0 comments on commit cba2c2f

Please sign in to comment.