From d5f4a94f6331299ab367da052c1c1358a3df71dd Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Wed, 11 May 2022 12:58:12 +0800 Subject: [PATCH 01/10] fix: eslint-parser worker --- eslint/babel-eslint-parser/src/client.cjs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/eslint/babel-eslint-parser/src/client.cjs b/eslint/babel-eslint-parser/src/client.cjs index 9bc52be6f48c..b86553ae105f 100644 --- a/eslint/babel-eslint-parser/src/client.cjs +++ b/eslint/babel-eslint-parser/src/client.cjs @@ -60,7 +60,7 @@ exports.WorkerClient = class WorkerClient extends Client { { env: WorkerClient.#worker_threads.SHARE_ENV }, ); - #signal = new Int32Array(new SharedArrayBuffer(4)); + #signal = new Int32Array(new SharedArrayBuffer(8)); constructor() { super((action, payload) => { @@ -73,10 +73,17 @@ exports.WorkerClient = class WorkerClient extends Client { ); Atomics.wait(this.#signal, 0, 0); - const { message } = WorkerClient.#worker_threads.receiveMessageOnPort( - subChannel.port2, - ); + let resp; + for (let i = 0; i < 100; i++) { + resp = WorkerClient.#worker_threads.receiveMessageOnPort( + subChannel.port2, + ); + if (resp) break; + Atomics.wait(this.#signal, 1, 0, 30); + } + + const message = resp.message; if (message.error) throw Object.assign(message.error, message.errorData); else return message.result; }); From 7ba8648389389d1959e5ae2741adaed2dfaaf839 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Thu, 12 May 2022 04:50:04 +0800 Subject: [PATCH 02/10] Update eslint/babel-eslint-parser/src/client.cjs --- eslint/babel-eslint-parser/src/client.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eslint/babel-eslint-parser/src/client.cjs b/eslint/babel-eslint-parser/src/client.cjs index b86553ae105f..a5e2ad74bda6 100644 --- a/eslint/babel-eslint-parser/src/client.cjs +++ b/eslint/babel-eslint-parser/src/client.cjs @@ -80,7 +80,7 @@ exports.WorkerClient = class WorkerClient extends Client { subChannel.port2, ); if (resp) break; - Atomics.wait(this.#signal, 1, 0, 30); + Atomics.wait(this.#signal, 1, 0, 5); } const message = resp.message; From a64196386a9bcba61fe871e000b6b04caaee1b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Mon, 16 May 2022 18:07:36 +0200 Subject: [PATCH 03/10] Add debug logs --- eslint/babel-eslint-parser/src/client.cjs | 26 ++++++++++++++++------- scripts/integration-tests/e2e-babel.sh | 6 +++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/eslint/babel-eslint-parser/src/client.cjs b/eslint/babel-eslint-parser/src/client.cjs index a5e2ad74bda6..76281ae88fd0 100644 --- a/eslint/babel-eslint-parser/src/client.cjs +++ b/eslint/babel-eslint-parser/src/client.cjs @@ -72,18 +72,28 @@ exports.WorkerClient = class WorkerClient extends Client { [subChannel.port1], ); - Atomics.wait(this.#signal, 0, 0); + let wakeReason = Atomics.wait(this.#signal, 0, 0); - let resp; - for (let i = 0; i < 100; i++) { - resp = WorkerClient.#worker_threads.receiveMessageOnPort( + let response; + let i = 0; + // Sometimes receiveMessageOnPort returns "undefined" instead of the + // actual response object. Try multiple times, with a timeout of 5ms + // on Atomic.wait starting from the second one. + do { + if (i > 0) wakeReason = Atomics.wait(this.#signal, 1, 0, 5); + + response = WorkerClient.#worker_threads.receiveMessageOnPort( subChannel.port2, ); - if (resp) break; - Atomics.wait(this.#signal, 1, 0, 5); - } - const message = resp.message; + if (i > 0 || !response) { + console.log( + `WORKER COMMUNICATION: i=${i}, wakeReason=${wakeReason}, hasResponse=${!!response}`, + ); + } + } while (!response && i++ < 100); + + const { message } = response; if (message.error) throw Object.assign(message.error, message.errorData); else return message.result; }); diff --git a/scripts/integration-tests/e2e-babel.sh b/scripts/integration-tests/e2e-babel.sh index 995bcad41a45..e21d3b4063a1 100755 --- a/scripts/integration-tests/e2e-babel.sh +++ b/scripts/integration-tests/e2e-babel.sh @@ -33,6 +33,10 @@ startLocalRegistry "$PWD"/scripts/integration-tests/verdaccio-config.yml node "$PWD"/scripts/integration-tests/utils/bump-babel-dependencies.js # Build and test -YARN_ENABLE_IMMUTABLE_INSTALLS=false make -j test-ci +YARN_ENABLE_IMMUTABLE_INSTALLS=false make -j build-standalone-ci +for i in {1..50}; do + echo "RUN NUMBER $i" + BABEL_ENV=test yarn jest --maxWorkers=4 --ci +done cleanup From 89dec0eee79612069ab9b3264cea462ac6381bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 18 May 2022 00:23:33 +0200 Subject: [PATCH 04/10] Always use a different SAB --- eslint/babel-eslint-parser/src/client.cjs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/eslint/babel-eslint-parser/src/client.cjs b/eslint/babel-eslint-parser/src/client.cjs index 76281ae88fd0..c3809f7f172e 100644 --- a/eslint/babel-eslint-parser/src/client.cjs +++ b/eslint/babel-eslint-parser/src/client.cjs @@ -64,15 +64,16 @@ exports.WorkerClient = class WorkerClient extends Client { constructor() { super((action, payload) => { - this.#signal[0] = 0; + const signal = new Int32Array(new SharedArrayBuffer(8)); + const subChannel = new WorkerClient.#worker_threads.MessageChannel(); this.#worker.postMessage( - { signal: this.#signal, port: subChannel.port1, action, payload }, + { signal, port: subChannel.port1, action, payload }, [subChannel.port1], ); - let wakeReason = Atomics.wait(this.#signal, 0, 0); + let wakeReason = Atomics.wait(signal, 0, 0); let response; let i = 0; @@ -80,7 +81,7 @@ exports.WorkerClient = class WorkerClient extends Client { // actual response object. Try multiple times, with a timeout of 5ms // on Atomic.wait starting from the second one. do { - if (i > 0) wakeReason = Atomics.wait(this.#signal, 1, 0, 5); + if (i > 0) wakeReason = Atomics.wait(signal, 1, 0, 5); response = WorkerClient.#worker_threads.receiveMessageOnPort( subChannel.port2, From b2903c882bdc80836f174f394660d7fa8efaba36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 18 May 2022 13:54:36 +0200 Subject: [PATCH 05/10] Only run eslint tests --- scripts/integration-tests/e2e-babel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/integration-tests/e2e-babel.sh b/scripts/integration-tests/e2e-babel.sh index e21d3b4063a1..c46b713dd308 100755 --- a/scripts/integration-tests/e2e-babel.sh +++ b/scripts/integration-tests/e2e-babel.sh @@ -36,7 +36,7 @@ node "$PWD"/scripts/integration-tests/utils/bump-babel-dependencies.js YARN_ENABLE_IMMUTABLE_INSTALLS=false make -j build-standalone-ci for i in {1..50}; do echo "RUN NUMBER $i" - BABEL_ENV=test yarn jest --maxWorkers=4 --ci + BABEL_ENV=test yarn jest --maxWorkers=4 --ci eslint done cleanup From 973038019b359df7dd10e2524cbbcbee36b9d498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 18 May 2022 14:06:34 +0200 Subject: [PATCH 06/10] Always log --- eslint/babel-eslint-parser/src/client.cjs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/eslint/babel-eslint-parser/src/client.cjs b/eslint/babel-eslint-parser/src/client.cjs index c3809f7f172e..146ae0be6fc8 100644 --- a/eslint/babel-eslint-parser/src/client.cjs +++ b/eslint/babel-eslint-parser/src/client.cjs @@ -87,11 +87,9 @@ exports.WorkerClient = class WorkerClient extends Client { subChannel.port2, ); - if (i > 0 || !response) { - console.log( - `WORKER COMMUNICATION: i=${i}, wakeReason=${wakeReason}, hasResponse=${!!response}`, - ); - } + console.log( + `WORKER COMMUNICATION: i=${i}, wakeReason=${wakeReason}, hasResponse=${!!response}`, + ); } while (!response && i++ < 100); const { message } = response; From b4f5b2075cb33457bfb1e3f520b9af4e4a459058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 19 May 2022 20:14:25 +0200 Subject: [PATCH 07/10] Run all tests --- scripts/integration-tests/e2e-babel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/integration-tests/e2e-babel.sh b/scripts/integration-tests/e2e-babel.sh index c46b713dd308..e21d3b4063a1 100755 --- a/scripts/integration-tests/e2e-babel.sh +++ b/scripts/integration-tests/e2e-babel.sh @@ -36,7 +36,7 @@ node "$PWD"/scripts/integration-tests/utils/bump-babel-dependencies.js YARN_ENABLE_IMMUTABLE_INSTALLS=false make -j build-standalone-ci for i in {1..50}; do echo "RUN NUMBER $i" - BABEL_ENV=test yarn jest --maxWorkers=4 --ci eslint + BABEL_ENV=test yarn jest --maxWorkers=4 --ci done cleanup From bc6a62029dc6252174e09550a6bf3f38f9c5d406 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Fri, 20 May 2022 03:35:51 +0800 Subject: [PATCH 08/10] Update eslint/babel-eslint-parser/src/client.cjs --- eslint/babel-eslint-parser/src/client.cjs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/eslint/babel-eslint-parser/src/client.cjs b/eslint/babel-eslint-parser/src/client.cjs index 146ae0be6fc8..4b327bf98134 100644 --- a/eslint/babel-eslint-parser/src/client.cjs +++ b/eslint/babel-eslint-parser/src/client.cjs @@ -87,9 +87,11 @@ exports.WorkerClient = class WorkerClient extends Client { subChannel.port2, ); - console.log( - `WORKER COMMUNICATION: i=${i}, wakeReason=${wakeReason}, hasResponse=${!!response}`, - ); + if (i > 0) { + console.log( + `WORKER COMMUNICATION: i=${i}, wakeReason=${wakeReason}, hasResponse=${!!response}`, + ); + } } while (!response && i++ < 100); const { message } = response; From 5794b3b169c14b8aae9d52dbc6c4c02ec8af9aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Sun, 22 May 2022 19:49:24 +0200 Subject: [PATCH 09/10] Revert as many changes as possible --- eslint/babel-eslint-parser/src/client.cjs | 31 ++++++----------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/eslint/babel-eslint-parser/src/client.cjs b/eslint/babel-eslint-parser/src/client.cjs index 4b327bf98134..7925d35b5c00 100644 --- a/eslint/babel-eslint-parser/src/client.cjs +++ b/eslint/babel-eslint-parser/src/client.cjs @@ -60,10 +60,12 @@ exports.WorkerClient = class WorkerClient extends Client { { env: WorkerClient.#worker_threads.SHARE_ENV }, ); - #signal = new Int32Array(new SharedArrayBuffer(8)); - constructor() { super((action, payload) => { + // We create a new SharedArrayBuffer every time rather than reusing + // the same one, otherwise sometimes its contents get corrupted and + // Atomics.wait wakes up too early. + // https://github.com/babel/babel/pull/14541 const signal = new Int32Array(new SharedArrayBuffer(8)); const subChannel = new WorkerClient.#worker_threads.MessageChannel(); @@ -73,28 +75,11 @@ exports.WorkerClient = class WorkerClient extends Client { [subChannel.port1], ); - let wakeReason = Atomics.wait(signal, 0, 0); - - let response; - let i = 0; - // Sometimes receiveMessageOnPort returns "undefined" instead of the - // actual response object. Try multiple times, with a timeout of 5ms - // on Atomic.wait starting from the second one. - do { - if (i > 0) wakeReason = Atomics.wait(signal, 1, 0, 5); - - response = WorkerClient.#worker_threads.receiveMessageOnPort( - subChannel.port2, - ); - - if (i > 0) { - console.log( - `WORKER COMMUNICATION: i=${i}, wakeReason=${wakeReason}, hasResponse=${!!response}`, - ); - } - } while (!response && i++ < 100); + Atomics.wait(signal, 0, 0); + const { message } = WorkerClient.#worker_threads.receiveMessageOnPort( + subChannel.port2, + ); - const { message } = response; if (message.error) throw Object.assign(message.error, message.errorData); else return message.result; }); From b504b4907cdadb904d097101c985c4ed86381259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Sun, 22 May 2022 23:34:25 +0200 Subject: [PATCH 10/10] Remove test loop --- scripts/integration-tests/e2e-babel.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/integration-tests/e2e-babel.sh b/scripts/integration-tests/e2e-babel.sh index e21d3b4063a1..995bcad41a45 100755 --- a/scripts/integration-tests/e2e-babel.sh +++ b/scripts/integration-tests/e2e-babel.sh @@ -33,10 +33,6 @@ startLocalRegistry "$PWD"/scripts/integration-tests/verdaccio-config.yml node "$PWD"/scripts/integration-tests/utils/bump-babel-dependencies.js # Build and test -YARN_ENABLE_IMMUTABLE_INSTALLS=false make -j build-standalone-ci -for i in {1..50}; do - echo "RUN NUMBER $i" - BABEL_ENV=test yarn jest --maxWorkers=4 --ci -done +YARN_ENABLE_IMMUTABLE_INSTALLS=false make -j test-ci cleanup