From a00ec036ada56ab09c790d64e5c2691892d6de49 Mon Sep 17 00:00:00 2001 From: Ran Yitzhaki Date: Thu, 8 Feb 2018 02:19:46 +0200 Subject: [PATCH 1/6] Add unique id for each worker and pass it to the child process.env.JEST_WORKER_ID --- packages/jest-worker/src/__tests__/index.test.js | 16 ++++++++++++++++ .../jest-worker/src/__tests__/worker.test.js | 12 ++++++++++++ packages/jest-worker/src/index.js | 5 ++++- packages/jest-worker/src/types.js | 1 + packages/jest-worker/src/worker.js | 4 +++- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/jest-worker/src/__tests__/index.test.js b/packages/jest-worker/src/__tests__/index.test.js index 7c9a422f09a6..927c14254270 100644 --- a/packages/jest-worker/src/__tests__/index.test.js +++ b/packages/jest-worker/src/__tests__/index.test.js @@ -122,10 +122,26 @@ it('tries instantiating workers with the right options', () => { expect(Worker.mock.calls[0][0]).toEqual({ forkOptions: {execArgv: []}, maxRetries: 6, + workerId: 1, workerPath: '/tmp/baz.js', }); }); +it('create multiple workers with unique worker ids', () => { + // eslint-disable-next-line no-new + new Farm('/tmp/baz.js', { + exposedMethods: ['foo', 'bar'], + forkOptions: {execArgv: []}, + maxRetries: 6, + numWorkers: 3, + }); + + expect(Worker).toHaveBeenCalledTimes(3); + expect(Worker.mock.calls[0][0].workerId).toEqual(1); + expect(Worker.mock.calls[1][0].workerId).toEqual(2); + expect(Worker.mock.calls[2][0].workerId).toEqual(3); +}); + it('makes a non-existing relative worker throw', () => { expect( () => diff --git a/packages/jest-worker/src/__tests__/worker.test.js b/packages/jest-worker/src/__tests__/worker.test.js index 4ab2d08aaee2..aacba5def4bf 100644 --- a/packages/jest-worker/src/__tests__/worker.test.js +++ b/packages/jest-worker/src/__tests__/worker.test.js @@ -57,6 +57,7 @@ it('passes fork options down to child_process.fork, adding the defaults', () => execPath: 'hello', }, maxRetries: 3, + workerId: process.env.JEST_WORKER_ID, workerPath: '/tmp/foo/bar/baz.js', }); @@ -70,6 +71,17 @@ it('passes fork options down to child_process.fork, adding the defaults', () => }); }); +it('passes workerId to the child process and assign it to env.JEST_WORKER_ID', () => { + new Worker({ + forkOptions: {}, + maxRetries: 3, + workerId: 2, + workerPath: '/tmp/foo', + }); + + expect(childProcess.fork.mock.calls[0][1].env.JEST_WORKER_ID).toEqual(2); +}); + it('initializes the child process with the given workerPath', () => { new Worker({ forkOptions: {}, diff --git a/packages/jest-worker/src/index.js b/packages/jest-worker/src/index.js index d0c49a054532..65f0bf26b1e6 100644 --- a/packages/jest-worker/src/index.js +++ b/packages/jest-worker/src/index.js @@ -67,13 +67,16 @@ export default class { } // Build the options once for all workers to avoid allocating extra objects. - const workerOptions = { + const sharedWorkerOptions = { forkOptions: options.forkOptions || {}, maxRetries: options.maxRetries || 3, workerPath, }; for (let i = 0; i < numWorkers; i++) { + const workerOptions = Object.assign({}, sharedWorkerOptions, { + workerId: i + 1, + }); const worker = new Worker(workerOptions); const workerStdout = worker.getStdout(); const workerStderr = worker.getStderr(); diff --git a/packages/jest-worker/src/types.js b/packages/jest-worker/src/types.js index 1c0f2d5bd7c5..16c4f9e99c42 100644 --- a/packages/jest-worker/src/types.js +++ b/packages/jest-worker/src/types.js @@ -47,6 +47,7 @@ export type WorkerOptions = {| forkOptions: ForkOptions, maxRetries: number, workerPath: string, + workerId: number, |}; // Messages passed from the parent to the children. diff --git a/packages/jest-worker/src/worker.js b/packages/jest-worker/src/worker.js index ca7be4e3614c..e087ea05adec 100644 --- a/packages/jest-worker/src/worker.js +++ b/packages/jest-worker/src/worker.js @@ -79,7 +79,9 @@ export default class { Object.assign( { cwd: process.cwd(), - env: process.env, + env: Object.assign({}, process.env, { + JEST_WORKER_ID: this._options.workerId, + }), // suppress --debug / --inspect flags while preserving others (like --harmony) execArgv: process.execArgv.filter(v => !/^--(debug|inspect)/.test(v)), silent: true, From 931f73a8aefd29660ddc6c4d4667e4742ea07c19 Mon Sep 17 00:00:00 2001 From: Ran Yitzhaki Date: Thu, 8 Feb 2018 03:10:22 +0200 Subject: [PATCH 2/6] update changelog with the addition of unique id for each worker --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37b11d761972..8f43d93ac711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## master +### Features + +* `[jest-worker]` Assign a unique id for each worker and pass it to the child + process. It will be available via `process.env.JEST_WORKER_ID` + ([#5494](https://github.com/facebook/jest/pull/5494)) + ## jest 22.2.1 ### Fixes From d8430be9368a11ee80a6adb8d2e609bf4c8ab3ce Mon Sep 17 00:00:00 2001 From: Ran Yitzhaki Date: Thu, 8 Feb 2018 03:27:43 +0200 Subject: [PATCH 3/6] Alphabetically sorted props --- packages/jest-worker/src/types.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-worker/src/types.js b/packages/jest-worker/src/types.js index 16c4f9e99c42..c40ed0e50e33 100644 --- a/packages/jest-worker/src/types.js +++ b/packages/jest-worker/src/types.js @@ -46,8 +46,8 @@ export type FarmOptions = { export type WorkerOptions = {| forkOptions: ForkOptions, maxRetries: number, - workerPath: string, workerId: number, + workerPath: string, |}; // Messages passed from the parent to the children. From 27d512eb99a73ca6d43a747dbf680bcde2647280 Mon Sep 17 00:00:00 2001 From: Ran Yitzhaki Date: Thu, 8 Feb 2018 03:28:11 +0200 Subject: [PATCH 4/6] remove non relevant comment --- packages/jest-worker/src/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/jest-worker/src/index.js b/packages/jest-worker/src/index.js index 65f0bf26b1e6..2193a4773009 100644 --- a/packages/jest-worker/src/index.js +++ b/packages/jest-worker/src/index.js @@ -66,7 +66,6 @@ export default class { workerPath = require.resolve(workerPath); } - // Build the options once for all workers to avoid allocating extra objects. const sharedWorkerOptions = { forkOptions: options.forkOptions || {}, maxRetries: options.maxRetries || 3, From ef15a6b16554d4077a63ce0e0785263b29a6b94c Mon Sep 17 00:00:00 2001 From: Ran Yitzhaki Date: Thu, 8 Feb 2018 03:41:03 +0200 Subject: [PATCH 5/6] document the addition of env.JEST_WORKER_ID on each worker child process --- packages/jest-worker/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/jest-worker/README.md b/packages/jest-worker/README.md index 2b4656f43169..bd0c2bc74713 100644 --- a/packages/jest-worker/README.md +++ b/packages/jest-worker/README.md @@ -130,6 +130,9 @@ overriding options through `forkOptions`. Finishes the workers by killing all workers. No further calls can be done to the `Worker` instance. +**Note:** Each worker has a unique id (index that starts with `1`) which is +available on `process.env.JEST_WORKER_ID` + # More examples ## Standard usage From 75670efbeed9d079999f75f6d5ebae5a79101519 Mon Sep 17 00:00:00 2001 From: Ran Yitzhaki Date: Thu, 8 Feb 2018 13:39:59 +0200 Subject: [PATCH 6/6] add example for documentation regarding JEST_WORKER_ID --- packages/jest-worker/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/jest-worker/README.md b/packages/jest-worker/README.md index bd0c2bc74713..cf4d08e41139 100644 --- a/packages/jest-worker/README.md +++ b/packages/jest-worker/README.md @@ -146,12 +146,13 @@ import Worker from 'jest-worker'; async function main() { const myWorker = new Worker(require.resolve('./worker'), { - exposedMethods: ['foo', 'bar'], + exposedMethods: ['foo', 'bar', 'getWorkerId'], numWorkers: 4, }); console.log(await myWorker.foo('Alice')); // "Hello from foo: Alice" console.log(await myWorker.bar('Bob')); // "Hello from bar: Bob" + console.log(await myWorker.getWorkerId()); // "3" -> this message has sent from the 3rd worker myWorker.end(); } @@ -169,6 +170,10 @@ export function foo(param) { export function bar(param) { return 'Hello from bar: ' + param; } + +export function getWorkerId() { + return process.env.JEST_WORKER_ID; +} ``` ## Bound worker usage: