Skip to content

Commit

Permalink
fix: add option to disable worker_threads in jest-worker (#7681)
Browse files Browse the repository at this point in the history
* fix: add option to disable `worker_threads` in `jest-worker`

* link to PR
  • Loading branch information
SimenB authored and cpojer committed Jan 23, 2019
1 parent 0e1855e commit 967b335
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
- `[jest-runner]` Instantiate the test environment class with the current `testPath` ([#7442](https://github.com/facebook/jest/pull/7442))
- `[jest-config]` Always resolve jest-environment-jsdom from jest-config ([#7476](https://github.com/facebook/jest/pull/7476))
- `[expect]` Improve report when assertion fails, part 6 ([#7621](https://github.com/facebook/jest/pull/7621))
- `[jest-worker]` Add `disableWorkerThreads` option to explicitly opt out of `worker_threads` even if available ([#7681](https://github.com/facebook/jest/pull/7681))

### Fixes

Expand Down Expand Up @@ -129,6 +130,7 @@
- `[jest-util]` [**BREAKING**] Remove long-deprecated globals for fake timers ([#7285](https://github.com/facebook/jest/pull/7285))
- `[*]` [**BREAKING**] Upgrade to Micromatch 3 ([#6650](https://github.com/facebook/jest/pull/6650))
- `[*]` [**BREAKING**] Remove regenerator-runtime injection ([#7595](https://github.com/facebook/jest/pull/7595))
- `[jest-worker]` Disable `worker_threads` to avoid issues with libraries to ready for it ([#7681](https://github.com/facebook/jest/pull/7681))
- `[docs]` Fix message property in custom matcher example to return a function instead of a constant. ([#7426](https://github.com/facebook/jest/pull/7426))
- `[jest-circus]` Standardize file naming in `jest-circus` ([#7301](https://github.com/facebook/jest/pull/7301))
- `[docs]` Add synchronous test.each setup ([#7150](https://github.com/facebook/jest/pull/7150))
Expand Down
1 change: 1 addition & 0 deletions packages/jest-cli/src/reporters/coverage_reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export default class CoverageReporter extends BaseReporter {
} else {
// $FlowFixMe: assignment of a worker with custom properties.
worker = new Worker(require.resolve('./coverage_worker'), {
disableWorkerThreads: true,
exposedMethods: ['worker'],
maxRetries: 2,
numWorkers: this._globalConfig.maxWorkers,
Expand Down
1 change: 1 addition & 0 deletions packages/jest-haste-map/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ class HasteMap extends EventEmitter {
} else {
// $FlowFixMe: assignment of a worker with custom properties.
this._worker = (new Worker(require.resolve('./worker'), {
disableWorkerThreads: true,
exposedMethods: ['getSha1', 'worker'],
maxRetries: 3,
numWorkers: this._options.maxWorkers,
Expand Down
1 change: 1 addition & 0 deletions packages/jest-runner/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class TestRunner {
) {
// $FlowFixMe: class object is augmented with worker when instantiating.
const worker: WorkerInterface = new Worker(TEST_WORKER_PATH, {
disableWorkerThreads: true,
exposedMethods: ['worker'],
forkOptions: {stdio: 'pipe'},
maxRetries: 3,
Expand Down
6 changes: 6 additions & 0 deletions packages/jest-worker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ Node 10 shipped with [worker-threads](https://nodejs.org/api/worker_threads.html

We will use worker threads where available. To enable in Node 10+, run the Node process with the `--experimental-worker` flag.

You can explicitly opt-out of this by passing `disableWorkerThreads: true`.

## API

The only exposed method is a constructor (`Worker`) that is initialized by passing the worker path, plus an options object.
Expand Down Expand Up @@ -89,6 +91,10 @@ Provide a custom worker pool to be used for spawning child processes. By default

The arguments that will be passed to the `setup` method during initialization.

#### `disableWorkerThreads: boolean` (optional)

`jest-worker` will automatically detect if `worker_threads` are available and use them. However, running under threads comes with [some caveats](https://nodejs.org/api/worker_threads.html#worker_threads_class_worker), and is still experimental, so you can `opt-out` of this and use `disableWorkerThreads: true`.

## Worker

The returned `Worker` instance has all the exposed methods, plus some additional ones to interact with the workers itself:
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-worker/src/WorkerPool.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class WorkerPool extends BaseWorkerPool implements WorkerPoolInterface {

createWorker(workerOptions: WorkerOptions): WorkerInterface {
let Worker;
if (canUseWorkerThreads()) {
if (!this._options.disableWorkerThreads && canUseWorkerThreads()) {
Worker = require('./workers/NodeThreadsWorker').default;
} else {
Worker = require('./workers/ChildProcessWorker').default;
Expand Down
29 changes: 29 additions & 0 deletions packages/jest-worker/src/__tests__/WorkerPool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,33 @@ describe('WorkerPool', () => {
onEnd,
);
});

it('should avoid NodeThreadWorker if passed disableWorkerThreads', () => {
jest.mock('worker_threads', () => 'Defined');
const workerPool = new WorkerPool('/path', {
disableWorkerThreads: true,
forkOptions: {},
maxRetries: 1,
numWorkers: 1,
workerId: 0,
workerPath: '/path',
});

const onStart = () => {};
const onEnd = () => {};
workerPool.send(0, {foo: 'bar'}, onStart, onEnd);

expect(ChildProcessWorker).toBeCalledWith({
forkOptions: {},
maxRetries: 1,
workerId: 0,
workerPath: '/path',
});
expect(NodeThreadWorker).not.toBeCalled();
expect(workerPool._workers[0].send).toBeCalledWith(
{foo: 'bar'},
onStart,
onEnd,
);
});
});
1 change: 1 addition & 0 deletions packages/jest-worker/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default class JestWorker {
this._options = {...options};

const workerPoolOptions: WorkerPoolOptions = {
disableWorkerThreads: this._options.disableWorkerThreads || false,
forkOptions: this._options.forkOptions || {},
maxRetries: this._options.maxRetries || 3,
numWorkers: this._options.numWorkers || Math.max(os.cpus().length - 1, 1),
Expand Down
2 changes: 2 additions & 0 deletions packages/jest-worker/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,15 @@ export type FarmOptions = {
workerPath: string,
options?: WorkerPoolOptions,
) => WorkerPoolInterface,
disableWorkerThreads?: boolean,
};

export type WorkerPoolOptions = {|
setupArgs: Array<mixed>,
forkOptions: ForkOptions,
maxRetries: number,
numWorkers: number,
disableWorkerThreads: boolean,
|};

export type WorkerOptions = {|
Expand Down

0 comments on commit 967b335

Please sign in to comment.