Skip to content

Commit

Permalink
chore: migrate jest-worker to TypeScript (#7853)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Feb 10, 2019
1 parent 00e52eb commit b49075e
Show file tree
Hide file tree
Showing 17 changed files with 197 additions and 229 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -24,6 +24,7 @@
- `[jest-util]`: Migrate to TypeScript ([#7844](https://github.com/facebook/jest/pull/7844))
- `[jest-watcher]`: Migrate to TypeScript ([#7843](https://github.com/facebook/jest/pull/7843))
- `[jest-mock]`: Migrate to TypeScript ([#7847](https://github.com/facebook/jest/pull/7847), [#7850](https://github.com/facebook/jest/pull/7850))
- `[jest-worker]`: Migrate to TypeScript ([#7853](https://github.com/facebook/jest/pull/7853))

### Performance

Expand Down
1 change: 0 additions & 1 deletion packages/jest-cli/src/reporters/coverage_reporter.js
Expand Up @@ -159,7 +159,6 @@ export default class CoverageReporter extends BaseReporter {
if (this._globalConfig.maxWorkers <= 1) {
worker = require('./coverage_worker');
} else {
// $FlowFixMe: assignment of a worker with custom properties.
worker = new Worker(require.resolve('./coverage_worker'), {
exposedMethods: ['worker'],
maxRetries: 2,
Expand Down
1 change: 0 additions & 1 deletion packages/jest-haste-map/src/index.js
Expand Up @@ -670,7 +670,6 @@ class HasteMap extends EventEmitter {
if ((options && options.forceInBand) || this._options.maxWorkers <= 1) {
this._worker = {getSha1, worker};
} else {
// $FlowFixMe: assignment of a worker with custom properties.
this._worker = (new Worker(require.resolve('./worker'), {
exposedMethods: ['getSha1', 'worker'],
maxRetries: 3,
Expand Down
1 change: 0 additions & 1 deletion packages/jest-runner/src/index.js
Expand Up @@ -98,7 +98,6 @@ class TestRunner {
onResult: OnTestSuccess,
onFailure: OnTestFailure,
) {
// $FlowFixMe: class object is augmented with worker when instantiating.
const worker: WorkerInterface = new Worker(TEST_WORKER_PATH, {
exposedMethods: ['worker'],
forkOptions: {stdio: 'pipe'},
Expand Down
2 changes: 2 additions & 0 deletions packages/jest-worker/package.json
Expand Up @@ -8,7 +8,9 @@
},
"license": "MIT",
"main": "build/index.js",
"types": "build/index.d.ts",
"dependencies": {
"@types/node": "*",
"merge-stream": "^1.0.1",
"supports-color": "^6.1.0"
},
Expand Down
Expand Up @@ -3,35 +3,32 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

'use strict';

import type {
import {
ChildMessage,
FarmOptions,
QueueChildMessage,
WorkerInterface,
OnStart,
OnEnd,
CHILD_MESSAGE_CALL,
} from './types';
import {CHILD_MESSAGE_CALL} from './types';

export default class Farm {
_computeWorkerKey: (string, ...Array<any>) => ?string;
_cacheKeys: {[string]: WorkerInterface, __proto__: null};
_computeWorkerKey: FarmOptions['computeWorkerKey'];
_cacheKeys: {[key: string]: WorkerInterface};
_callback: Function;
_last: Array<QueueChildMessage>;
_locks: Array<boolean>;
_numOfWorkers: number;
_offset: number;
_queue: Array<?QueueChildMessage>;
_queue: Array<QueueChildMessage | null>;

constructor(
numOfWorkers: number,
callback: Function,
computeWorkerKey?: (string, ...Array<any>) => ?string,
computeWorkerKey?: FarmOptions['computeWorkerKey'],
) {
this._callback = callback;
this._numOfWorkers = numOfWorkers;
Expand All @@ -45,16 +42,16 @@ export default class Farm {
}
}

doWork(method: string, ...args: Array<any>): Promise<mixed> {
doWork(method: string, ...args: Array<any>): Promise<unknown> {
return new Promise((resolve, reject) => {
const computeWorkerKey = this._computeWorkerKey;
const request: ChildMessage = [CHILD_MESSAGE_CALL, false, method, args];

let worker: ?WorkerInterface = null;
let hash: ?string = null;
let worker: WorkerInterface | null = null;
let hash: string | null = null;

if (computeWorkerKey) {
hash = computeWorkerKey.apply(this, [method].concat(args));
hash = computeWorkerKey.call(this, method, ...args);
worker = hash == null ? null : this._cacheKeys[hash];
}

Expand All @@ -64,7 +61,7 @@ export default class Farm {
}
};

const onEnd: OnEnd = (error: ?Error, result: ?mixed) => {
const onEnd: OnEnd = (error: Error | null, result: unknown) => {
if (error) {
reject(error);
} else {
Expand All @@ -81,11 +78,11 @@ export default class Farm {
});
}

_getNextJob(workerId: number): ?QueueChildMessage {
_getNextJob(workerId: number): QueueChildMessage | null {
let queueHead = this._queue[workerId];

while (queueHead && queueHead.request[1]) {
queueHead = queueHead.next;
queueHead = queueHead.next || null;
}

this._queue[workerId] = queueHead;
Expand All @@ -104,7 +101,7 @@ export default class Farm {
return this;
}

const onEnd = (error: ?Error, result: mixed) => {
const onEnd = (error: Error | null, result: unknown) => {
job.onEnd(error, result);
this.unlock(workerId);
this._process(workerId);
Expand Down
Expand Up @@ -3,15 +3,11 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

'use strict';

import BaseWorkerPool from './base/BaseWorkerPool';

import type {
import {
ChildMessage,
WorkerOptions,
OnStart,
Expand Down
Expand Up @@ -3,26 +3,24 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

'use strict';

import mergeStream from 'merge-stream';
import path from 'path';
import mergeStream from 'merge-stream';

import {CHILD_MESSAGE_END} from '../types';

import type {Readable} from 'stream';
import type {WorkerPoolOptions, WorkerOptions, WorkerInterface} from '../types';
import {
CHILD_MESSAGE_END,
WorkerPoolOptions,
WorkerOptions,
WorkerInterface,
} from '../types';

/* istanbul ignore next */
const emptyMethod = () => {};

export default class BaseWorkerPool {
_stderr: Readable;
_stdout: Readable;
_stderr: NodeJS.ReadableStream;
_stdout: NodeJS.ReadableStream;
_options: WorkerPoolOptions;
_workers: Array<WorkerInterface>;

Expand Down Expand Up @@ -67,11 +65,11 @@ export default class BaseWorkerPool {
this._stderr = stderr;
}

getStderr(): Readable {
getStderr(): NodeJS.ReadableStream {
return this._stderr;
}

getStdout(): Readable {
getStdout(): NodeJS.ReadableStream {
return this._stdout;
}

Expand All @@ -83,7 +81,7 @@ export default class BaseWorkerPool {
return this._workers[workerId];
}

createWorker(workerOptions: WorkerOptions): WorkerInterface {
createWorker(_workerOptions: WorkerOptions): WorkerInterface {
throw Error('Missing method createWorker in WorkerPool');
}

Expand Down
Expand Up @@ -3,39 +3,30 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

'use strict';

import os from 'os';
import WorkerPool from './WorkerPool';
import Farm from './Farm';
import type {
WorkerPoolInterface,
WorkerPoolOptions,
FarmOptions,
} from './types';
import type {Readable} from 'stream';
import {WorkerPoolInterface, WorkerPoolOptions, FarmOptions} from './types';

function getExposedMethods(
workerPath: string,
options: FarmOptions,
): $ReadOnlyArray<string> {
): ReadonlyArray<string> {
let exposedMethods = options.exposedMethods;

// If no methods list is given, try getting it by auto-requiring the module.
if (!exposedMethods) {
// $FlowFixMe: This has to be a dynamic require.
const module: Function | Object = require(workerPath);

exposedMethods = Object.keys(module).filter(
// @ts-ignore: no index
name => typeof module[name] === 'function',
);

if (typeof module === 'function') {
exposedMethods.push('default');
exposedMethods = [...exposedMethods, 'default'];
}
}

Expand Down Expand Up @@ -75,6 +66,7 @@ export default class JestWorker {

constructor(workerPath: string, options?: FarmOptions) {
this._options = {...options};
this._ending = false;

const workerPoolOptions: WorkerPoolOptions = {
enableWorkerThreads: this._options.enableWorkerThreads || false,
Expand All @@ -84,9 +76,15 @@ export default class JestWorker {
setupArgs: this._options.setupArgs || [],
};

this._workerPool = this._options.WorkerPool
? new this._options.WorkerPool(workerPath, workerPoolOptions)
: new WorkerPool(workerPath, workerPoolOptions);
if (this._options.WorkerPool) {
// @ts-ignore: constructor target any?
this._workerPool = new this._options.WorkerPool(
workerPath,
workerPoolOptions,
);
} else {
this._workerPool = new WorkerPool(workerPath, workerPoolOptions);
}

this._farm = new Farm(
workerPoolOptions.numWorkers,
Expand All @@ -107,7 +105,7 @@ export default class JestWorker {
throw new TypeError('Cannot define a method called ' + name);
}

// $FlowFixMe: dynamic extension of the class instance is expected.
// @ts-ignore: dynamic extension of the class instance is expected.
this[name] = this._callFunctionWithArgs.bind(this, name);
});
}
Expand All @@ -120,11 +118,11 @@ export default class JestWorker {
return this._farm.doWork(method, ...args);
}

getStderr(): Readable {
getStderr(): NodeJS.ReadableStream {
return this._workerPool.getStderr();
}

getStdout(): Readable {
getStdout(): NodeJS.ReadableStream {
return this._workerPool.getStdout();
}

Expand Down

0 comments on commit b49075e

Please sign in to comment.