From 7df0edbd60e53f789312ca64920c37d827aa69dc Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 17 Oct 2026 00:42:38 +0200 Subject: [PATCH] fix!: require Node.js versions with ESM cluster support (#3348) * fix!: require Node.js versions with ESM cluster support Migrate cluster fixtures and benchmarks to ESM, retain explicit CommonJS coverage, and test the exact minimum Node.js releases in CI. BREAKING CHANGE: Node.js ^22.18.0 || >=24.3.0 is required. Upgrade older Node.js installations before updating Poolifier. Fixes #782 * fix(examples): remove CommonJS cluster build workarounds Build and start all six cluster and hybrid server examples as ESM. Remove redundant start:esm scripts and extension-dependent worker paths; retain public CommonJS library support. * fix(examples): declare Node.js requirements for ESM cluster workers Align the six standalone cluster and hybrid examples with the supported Node.js range. This declares compatibility and enables package-manager engine checks without adding a runtime guard or changing dependencies. * docs: remove unnecessary ESM background from README * docs: remove unnecessary cluster startup explanations --- .github/workflows/ci.yml | 5 ++ README.md | 2 +- benchmarks/benchmarks-utils.mjs | 4 +- ...{cluster-worker.cjs => cluster-worker.mjs} | 10 +-- eslint.config.js | 1 - .../express-cluster/package.json | 6 +- .../express-cluster/rollup.config.ts | 19 ++--- .../express-cluster/src/main.ts | 7 +- .../express-hybrid/package.json | 6 +- .../express-hybrid/rollup.config.ts | 19 ++--- .../express-hybrid/src/main.ts | 6 +- .../fastify-cluster/package.json | 6 +- .../fastify-cluster/rollup.config.ts | 19 ++--- .../fastify-cluster/src/main.ts | 7 +- .../fastify-hybrid/package.json | 6 +- .../fastify-hybrid/rollup.config.ts | 19 ++--- .../fastify-hybrid/src/main.ts | 6 +- .../ws-cluster/package.json | 6 +- .../ws-cluster/rollup.config.ts | 19 ++--- .../ws-cluster/src/main.ts | 7 +- .../ws-hybrid/package.json | 6 +- .../ws-hybrid/rollup.config.ts | 19 ++--- .../ws-hybrid/src/main.ts | 6 +- package.json | 2 +- tests/pools/abstract-pool.test.mjs | 42 +++++------ tests/pools/cluster/dynamic.test.mjs | 10 +-- tests/pools/cluster/fixed.test.mjs | 20 +++--- tests/pools/cluster/module-formats.test.mjs | 70 +++++++++++++++++++ tests/pools/prototype-pollution.test.mjs | 4 +- .../selection-strategies-utils.test.mjs | 2 +- .../selection-strategies.test.mjs | 4 +- tests/pools/utils.test.mjs | 4 +- tests/pools/worker-exit.test.mjs | 2 +- tests/pools/worker-node.test.mjs | 6 +- ...ncErrorWorker.cjs => asyncErrorWorker.mjs} | 7 +- .../{asyncWorker.cjs => asyncWorker.mjs} | 7 +- .../{crashWorker.cjs => crashWorker.mjs} | 7 +- tests/worker-files/cluster/echoWorker.mjs | 14 ++++ tests/worker-files/cluster/emptyWorker.cjs | 12 ---- tests/worker-files/cluster/emptyWorker.mjs | 11 +++ .../{errorWorker.cjs => errorWorker.mjs} | 5 +- ....cjs => longRunningWorkerHardBehavior.mjs} | 7 +- ....cjs => longRunningWorkerSoftBehavior.mjs} | 7 +- ...orker.cjs => prototypePollutionWorker.mjs} | 5 +- ...js => testMultipleTaskFunctionsWorker.mjs} | 9 ++- ....cjs => testTaskFunctionObjectsWorker.mjs} | 9 ++- .../{testWorker.cjs => testWorker.mjs} | 9 ++- 47 files changed, 256 insertions(+), 230 deletions(-) rename benchmarks/internal/{cluster-worker.cjs => cluster-worker.mjs} (55%) create mode 100644 tests/pools/cluster/module-formats.test.mjs rename tests/worker-files/cluster/{asyncErrorWorker.cjs => asyncErrorWorker.mjs} (66%) rename tests/worker-files/cluster/{asyncWorker.cjs => asyncWorker.mjs} (58%) rename tests/worker-files/cluster/{crashWorker.cjs => crashWorker.mjs} (85%) create mode 100644 tests/worker-files/cluster/echoWorker.mjs delete mode 100644 tests/worker-files/cluster/emptyWorker.cjs create mode 100644 tests/worker-files/cluster/emptyWorker.mjs rename tests/worker-files/cluster/{errorWorker.cjs => errorWorker.mjs} (53%) rename tests/worker-files/cluster/{longRunningWorkerHardBehavior.cjs => longRunningWorkerHardBehavior.mjs} (59%) rename tests/worker-files/cluster/{longRunningWorkerSoftBehavior.cjs => longRunningWorkerSoftBehavior.mjs} (60%) rename tests/worker-files/cluster/{prototypePollutionWorker.cjs => prototypePollutionWorker.mjs} (75%) rename tests/worker-files/cluster/{testMultipleTaskFunctionsWorker.cjs => testMultipleTaskFunctionsWorker.mjs} (72%) rename tests/worker-files/cluster/{testTaskFunctionObjectsWorker.cjs => testTaskFunctionObjectsWorker.mjs} (68%) rename tests/worker-files/cluster/{testWorker.cjs => testWorker.mjs} (62%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d9ef6423..d4727cd99 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,11 @@ jobs: matrix: os: [windows-latest, macos-latest, ubuntu-latest] node: ['22.x', '24.x', 'latest'] + include: + - os: ubuntu-latest + node: '22.18.0' + - os: ubuntu-latest + node: '24.3.0' name: Node.js ${{ matrix.node }} on ${{ matrix.os }} diff --git a/README.md b/README.md index b6c2d34f6..97c1014b6 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ Remember that workers can only send and receive structured-cloneable data. ## Node.js versions -Node.js versions >= 22.x.x are supported. +Supported Node.js versions are **22.18.0 or later in the 22.x line**, or **24.3.0 and later**. ## [API](./docs/api.md) diff --git a/benchmarks/benchmarks-utils.mjs b/benchmarks/benchmarks-utils.mjs index 53755f8be..5a42d462c 100644 --- a/benchmarks/benchmarks-utils.mjs +++ b/benchmarks/benchmarks-utils.mjs @@ -21,7 +21,7 @@ const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => { return new DynamicClusterPool( Math.floor(poolSize / 2), poolSize, - './benchmarks/internal/cluster-worker.cjs', + './benchmarks/internal/cluster-worker.mjs', poolOptions ) case WorkerTypes.thread: @@ -38,7 +38,7 @@ const buildPoolifierPool = (workerType, poolType, poolSize, poolOptions) => { case WorkerTypes.cluster: return new FixedClusterPool( poolSize, - './benchmarks/internal/cluster-worker.cjs', + './benchmarks/internal/cluster-worker.mjs', poolOptions ) case WorkerTypes.thread: diff --git a/benchmarks/internal/cluster-worker.cjs b/benchmarks/internal/cluster-worker.mjs similarity index 55% rename from benchmarks/internal/cluster-worker.cjs rename to benchmarks/internal/cluster-worker.mjs index 757c6961e..bb2927467 100644 --- a/benchmarks/internal/cluster-worker.cjs +++ b/benchmarks/internal/cluster-worker.mjs @@ -1,8 +1,8 @@ -const { isPrimary } = require('node:cluster') +import { isPrimary } from 'node:cluster' -const { ClusterWorker } = require('../../lib/index.cjs') -const { TaskFunctions } = require('../benchmarks-types.cjs') -const { executeTaskFunction } = require('../benchmarks-utils.cjs') +import { ClusterWorker } from '../../lib/index.mjs' +import { TaskFunctions } from '../benchmarks-types.cjs' +import { executeTaskFunction } from '../benchmarks-utils.mjs' const taskFunction = data => { data = data || {} @@ -14,4 +14,4 @@ const taskFunction = data => { return res } -module.exports = new ClusterWorker(taskFunction) +export default new ClusterWorker(taskFunction) diff --git a/eslint.config.js b/eslint.config.js index 9c358f519..c1b230d3d 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -57,7 +57,6 @@ export default defineConfig([ languageOptions: { parserOptions: { projectService: true, - // eslint-disable-next-line n/no-unsupported-features/node-builtins tsconfigRootDir: import.meta.dirname, }, }, diff --git a/examples/typescript/http-server-pool/express-cluster/package.json b/examples/typescript/http-server-pool/express-cluster/package.json index f6b17f046..dc0a11d44 100644 --- a/examples/typescript/http-server-pool/express-cluster/package.json +++ b/examples/typescript/http-server-pool/express-cluster/package.json @@ -5,11 +5,13 @@ "description": "Express cluster pool", "main": "dist/main.js", "type": "module", + "engines": { + "node": "^22.18.0 || >=24.3.0" + }, "packageManager": "pnpm@12.11.2", "scripts": { "build": "rollup --config --configPlugin typescript", - "start": "node --enable-source-maps dist/main.cjs", - "start:esm": "node --enable-source-maps dist/main.js", + "start": "node --enable-source-maps dist/main.js", "test": "echo \"Error: no test specified\" && exit 1", "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo", "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000" diff --git a/examples/typescript/http-server-pool/express-cluster/rollup.config.ts b/examples/typescript/http-server-pool/express-cluster/rollup.config.ts index 1ed40f58c..f74971960 100644 --- a/examples/typescript/http-server-pool/express-cluster/rollup.config.ts +++ b/examples/typescript/http-server-pool/express-cluster/rollup.config.ts @@ -5,20 +5,11 @@ import del from 'rollup-plugin-delete' export default defineConfig({ external: ['express', /^node:*/, 'poolifier'], input: ['./src/main.ts', './src/worker.ts'], - output: [ - { - chunkFileNames: '[name]-[hash].cjs', - dir: './dist', - entryFileNames: '[name].cjs', - format: 'cjs', - sourcemap: true, - }, - { - dir: './dist', - format: 'esm', - sourcemap: true, - }, - ], + output: { + dir: './dist', + format: 'esm', + sourcemap: true, + }, plugins: [ typescript({ compilerOptions: { diff --git a/examples/typescript/http-server-pool/express-cluster/src/main.ts b/examples/typescript/http-server-pool/express-cluster/src/main.ts index 355c5a6b5..fbbf341f7 100644 --- a/examples/typescript/http-server-pool/express-cluster/src/main.ts +++ b/examples/typescript/http-server-pool/express-cluster/src/main.ts @@ -1,13 +1,10 @@ -import { dirname, extname, join } from 'node:path' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { availableParallelism, FixedClusterPool } from 'poolifier' import type { WorkerData, WorkerResponse } from './types.js' -const workerFile = join( - dirname(fileURLToPath(import.meta.url)), - `worker${extname(fileURLToPath(import.meta.url))}` -) +const workerFile = join(dirname(fileURLToPath(import.meta.url)), 'worker.js') const pool = new FixedClusterPool( availableParallelism(), diff --git a/examples/typescript/http-server-pool/express-hybrid/package.json b/examples/typescript/http-server-pool/express-hybrid/package.json index 1c6ecde3b..f21774b23 100644 --- a/examples/typescript/http-server-pool/express-hybrid/package.json +++ b/examples/typescript/http-server-pool/express-hybrid/package.json @@ -5,11 +5,13 @@ "description": "Express hybrid pool", "main": "dist/main.js", "type": "module", + "engines": { + "node": "^22.18.0 || >=24.3.0" + }, "packageManager": "pnpm@12.11.2", "scripts": { "build": "rollup --config --configPlugin typescript", - "start": "node --enable-source-maps dist/main.cjs", - "start:esm": "node --enable-source-maps dist/main.js", + "start": "node --enable-source-maps dist/main.js", "test": "echo \"Error: no test specified\" && exit 1", "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo", "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000" diff --git a/examples/typescript/http-server-pool/express-hybrid/rollup.config.ts b/examples/typescript/http-server-pool/express-hybrid/rollup.config.ts index e80bc482f..4e492c380 100644 --- a/examples/typescript/http-server-pool/express-hybrid/rollup.config.ts +++ b/examples/typescript/http-server-pool/express-hybrid/rollup.config.ts @@ -9,20 +9,11 @@ export default defineConfig({ './src/express-worker.ts', './src/request-handler-worker.ts', ], - output: [ - { - chunkFileNames: '[name]-[hash].cjs', - dir: './dist', - entryFileNames: '[name].cjs', - format: 'cjs', - sourcemap: true, - }, - { - dir: './dist', - format: 'esm', - sourcemap: true, - }, - ], + output: { + dir: './dist', + format: 'esm', + sourcemap: true, + }, plugins: [ typescript({ compilerOptions: { diff --git a/examples/typescript/http-server-pool/express-hybrid/src/main.ts b/examples/typescript/http-server-pool/express-hybrid/src/main.ts index 60c724889..17155bdf3 100644 --- a/examples/typescript/http-server-pool/express-hybrid/src/main.ts +++ b/examples/typescript/http-server-pool/express-hybrid/src/main.ts @@ -1,4 +1,4 @@ -import { dirname, extname, join } from 'node:path' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { availableParallelism, FixedClusterPool } from 'poolifier' @@ -6,12 +6,12 @@ import type { ClusterWorkerData, ClusterWorkerResponse } from './types.js' const expressWorkerFile = join( dirname(fileURLToPath(import.meta.url)), - `express-worker${extname(fileURLToPath(import.meta.url))}` + 'express-worker.js' ) const requestHandlerWorkerFile = join( dirname(fileURLToPath(import.meta.url)), - `request-handler-worker${extname(fileURLToPath(import.meta.url))}` + 'request-handler-worker.js' ) const pool = new FixedClusterPool( diff --git a/examples/typescript/http-server-pool/fastify-cluster/package.json b/examples/typescript/http-server-pool/fastify-cluster/package.json index c07ebe024..bd0d69e52 100644 --- a/examples/typescript/http-server-pool/fastify-cluster/package.json +++ b/examples/typescript/http-server-pool/fastify-cluster/package.json @@ -5,11 +5,13 @@ "description": "Fastify cluster pool", "main": "dist/main.js", "type": "module", + "engines": { + "node": "^22.18.0 || >=24.3.0" + }, "packageManager": "pnpm@12.11.2", "scripts": { "build": "rollup --config --configPlugin typescript", - "start": "node --enable-source-maps dist/main.cjs", - "start:esm": "node --enable-source-maps dist/main.js", + "start": "node --enable-source-maps dist/main.js", "test": "echo \"Error: no test specified\" && exit 1", "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo", "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000" diff --git a/examples/typescript/http-server-pool/fastify-cluster/rollup.config.ts b/examples/typescript/http-server-pool/fastify-cluster/rollup.config.ts index 836f417ad..0cf7523fd 100644 --- a/examples/typescript/http-server-pool/fastify-cluster/rollup.config.ts +++ b/examples/typescript/http-server-pool/fastify-cluster/rollup.config.ts @@ -5,20 +5,11 @@ import del from 'rollup-plugin-delete' export default defineConfig({ external: ['fastify', /^node:*/, 'poolifier'], input: ['./src/main.ts', './src/worker.ts'], - output: [ - { - chunkFileNames: '[name]-[hash].cjs', - dir: './dist', - entryFileNames: '[name].cjs', - format: 'cjs', - sourcemap: true, - }, - { - dir: './dist', - format: 'esm', - sourcemap: true, - }, - ], + output: { + dir: './dist', + format: 'esm', + sourcemap: true, + }, plugins: [ typescript({ compilerOptions: { diff --git a/examples/typescript/http-server-pool/fastify-cluster/src/main.ts b/examples/typescript/http-server-pool/fastify-cluster/src/main.ts index d85b73692..4b07e8063 100644 --- a/examples/typescript/http-server-pool/fastify-cluster/src/main.ts +++ b/examples/typescript/http-server-pool/fastify-cluster/src/main.ts @@ -1,13 +1,10 @@ -import { dirname, extname, join } from 'node:path' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { availableParallelism, FixedClusterPool } from 'poolifier' import type { WorkerData, WorkerResponse } from './types.js' -const workerFile = join( - dirname(fileURLToPath(import.meta.url)), - `worker${extname(fileURLToPath(import.meta.url))}` -) +const workerFile = join(dirname(fileURLToPath(import.meta.url)), 'worker.js') const pool = new FixedClusterPool( availableParallelism(), diff --git a/examples/typescript/http-server-pool/fastify-hybrid/package.json b/examples/typescript/http-server-pool/fastify-hybrid/package.json index ffb6cad38..cf309abad 100644 --- a/examples/typescript/http-server-pool/fastify-hybrid/package.json +++ b/examples/typescript/http-server-pool/fastify-hybrid/package.json @@ -5,11 +5,13 @@ "description": "Fastify hybrid pool", "main": "dist/main.js", "type": "module", + "engines": { + "node": "^22.18.0 || >=24.3.0" + }, "packageManager": "pnpm@12.11.2", "scripts": { "build": "rollup --config --configPlugin typescript", - "start": "node --enable-source-maps dist/main.cjs", - "start:esm": "node --enable-source-maps dist/main.js", + "start": "node --enable-source-maps dist/main.js", "test": "echo \"Error: no test specified\" && exit 1", "benchmark:echo": "autocannon -c 100 -d 30 -p 10 -m POST -H Content-Type=application/json -b '{\"key1\":\"value1\", \"key2\":\"value2\"}' http://localhost:8080/api/echo", "benchmark:factorial": "autocannon -c 100 -d 30 -p 10 http://localhost:8080/api/factorial/50000" diff --git a/examples/typescript/http-server-pool/fastify-hybrid/rollup.config.ts b/examples/typescript/http-server-pool/fastify-hybrid/rollup.config.ts index c978be244..1caa123c3 100644 --- a/examples/typescript/http-server-pool/fastify-hybrid/rollup.config.ts +++ b/examples/typescript/http-server-pool/fastify-hybrid/rollup.config.ts @@ -9,20 +9,11 @@ export default defineConfig({ './src/fastify-worker.ts', './src/request-handler-worker.ts', ], - output: [ - { - chunkFileNames: '[name]-[hash].cjs', - dir: './dist', - entryFileNames: '[name].cjs', - format: 'cjs', - sourcemap: true, - }, - { - dir: './dist', - format: 'esm', - sourcemap: true, - }, - ], + output: { + dir: './dist', + format: 'esm', + sourcemap: true, + }, plugins: [ typescript({ compilerOptions: { diff --git a/examples/typescript/http-server-pool/fastify-hybrid/src/main.ts b/examples/typescript/http-server-pool/fastify-hybrid/src/main.ts index 60e8655ed..e9662dae5 100644 --- a/examples/typescript/http-server-pool/fastify-hybrid/src/main.ts +++ b/examples/typescript/http-server-pool/fastify-hybrid/src/main.ts @@ -1,4 +1,4 @@ -import { dirname, extname, join } from 'node:path' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { availableParallelism, FixedClusterPool } from 'poolifier' @@ -6,12 +6,12 @@ import type { ClusterWorkerData, ClusterWorkerResponse } from './types.js' const fastifyWorkerFile = join( dirname(fileURLToPath(import.meta.url)), - `fastify-worker${extname(fileURLToPath(import.meta.url))}` + 'fastify-worker.js' ) const requestHandlerWorkerFile = join( dirname(fileURLToPath(import.meta.url)), - `request-handler-worker${extname(fileURLToPath(import.meta.url))}` + 'request-handler-worker.js' ) const pool = new FixedClusterPool( diff --git a/examples/typescript/websocket-server-pool/ws-cluster/package.json b/examples/typescript/websocket-server-pool/ws-cluster/package.json index 95cc778fe..ea280aec4 100644 --- a/examples/typescript/websocket-server-pool/ws-cluster/package.json +++ b/examples/typescript/websocket-server-pool/ws-cluster/package.json @@ -5,11 +5,13 @@ "description": "ws cluster pool", "main": "dist/main.js", "type": "module", + "engines": { + "node": "^22.18.0 || >=24.3.0" + }, "packageManager": "pnpm@12.11.2", "scripts": { "build": "rollup --config --configPlugin typescript", - "start": "node --enable-source-maps dist/main.cjs", - "start:esm": "node --enable-source-maps dist/main.js", + "start": "node --enable-source-maps dist/main.js", "test": "echo \"Error: no test specified\" && exit 1", "test:requests": "node requests.js" }, diff --git a/examples/typescript/websocket-server-pool/ws-cluster/rollup.config.ts b/examples/typescript/websocket-server-pool/ws-cluster/rollup.config.ts index 023ccbe4f..4333dde31 100644 --- a/examples/typescript/websocket-server-pool/ws-cluster/rollup.config.ts +++ b/examples/typescript/websocket-server-pool/ws-cluster/rollup.config.ts @@ -5,20 +5,11 @@ import del from 'rollup-plugin-delete' export default defineConfig({ external: [/^node:*/, 'poolifier', 'ws'], input: ['./src/main.ts', './src/worker.ts'], - output: [ - { - chunkFileNames: '[name]-[hash].cjs', - dir: './dist', - entryFileNames: '[name].cjs', - format: 'cjs', - sourcemap: true, - }, - { - dir: './dist', - format: 'esm', - sourcemap: true, - }, - ], + output: { + dir: './dist', + format: 'esm', + sourcemap: true, + }, plugins: [ typescript({ compilerOptions: { diff --git a/examples/typescript/websocket-server-pool/ws-cluster/src/main.ts b/examples/typescript/websocket-server-pool/ws-cluster/src/main.ts index 654be2ba8..93b931cb1 100644 --- a/examples/typescript/websocket-server-pool/ws-cluster/src/main.ts +++ b/examples/typescript/websocket-server-pool/ws-cluster/src/main.ts @@ -1,13 +1,10 @@ -import { dirname, extname, join } from 'node:path' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { availableParallelism, FixedClusterPool } from 'poolifier' import type { WorkerData, WorkerResponse } from './types.js' -const workerFile = join( - dirname(fileURLToPath(import.meta.url)), - `worker${extname(fileURLToPath(import.meta.url))}` -) +const workerFile = join(dirname(fileURLToPath(import.meta.url)), 'worker.js') const pool = new FixedClusterPool( availableParallelism(), diff --git a/examples/typescript/websocket-server-pool/ws-hybrid/package.json b/examples/typescript/websocket-server-pool/ws-hybrid/package.json index c131a2b65..58745a7f8 100644 --- a/examples/typescript/websocket-server-pool/ws-hybrid/package.json +++ b/examples/typescript/websocket-server-pool/ws-hybrid/package.json @@ -5,11 +5,13 @@ "description": "ws hybrid pool", "main": "dist/main.js", "type": "module", + "engines": { + "node": "^22.18.0 || >=24.3.0" + }, "packageManager": "pnpm@12.11.2", "scripts": { "build": "rollup --config --configPlugin typescript", - "start": "node --enable-source-maps dist/main.cjs", - "start:esm": "node --enable-source-maps dist/main.js", + "start": "node --enable-source-maps dist/main.js", "test": "echo \"Error: no test specified\" && exit 1", "test:requests": "node requests.js" }, diff --git a/examples/typescript/websocket-server-pool/ws-hybrid/rollup.config.ts b/examples/typescript/websocket-server-pool/ws-hybrid/rollup.config.ts index d504c5dd9..6575b4ecd 100644 --- a/examples/typescript/websocket-server-pool/ws-hybrid/rollup.config.ts +++ b/examples/typescript/websocket-server-pool/ws-hybrid/rollup.config.ts @@ -9,20 +9,11 @@ export default defineConfig({ './src/websocket-server-worker.ts', './src/request-handler-worker.ts', ], - output: [ - { - chunkFileNames: '[name]-[hash].cjs', - dir: './dist', - entryFileNames: '[name].cjs', - format: 'cjs', - sourcemap: true, - }, - { - dir: './dist', - format: 'esm', - sourcemap: true, - }, - ], + output: { + dir: './dist', + format: 'esm', + sourcemap: true, + }, plugins: [ typescript({ compilerOptions: { diff --git a/examples/typescript/websocket-server-pool/ws-hybrid/src/main.ts b/examples/typescript/websocket-server-pool/ws-hybrid/src/main.ts index 13f78249f..c24b130b1 100644 --- a/examples/typescript/websocket-server-pool/ws-hybrid/src/main.ts +++ b/examples/typescript/websocket-server-pool/ws-hybrid/src/main.ts @@ -1,4 +1,4 @@ -import { dirname, extname, join } from 'node:path' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { availableParallelism, FixedClusterPool } from 'poolifier' @@ -6,12 +6,12 @@ import type { ClusterWorkerData, ClusterWorkerResponse } from './types.js' const webSocketServerWorkerFile = join( dirname(fileURLToPath(import.meta.url)), - `websocket-server-worker${extname(fileURLToPath(import.meta.url))}` + 'websocket-server-worker.js' ) const requestHandlerWorkerFile = join( dirname(fileURLToPath(import.meta.url)), - `request-handler-worker${extname(fileURLToPath(import.meta.url))}` + 'request-handler-worker.js' ) const pool = new FixedClusterPool( diff --git a/package.json b/package.json index 8a520bb2b..61d88dfcb 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "postpublish": "rm -rf ./package" }, "engines": { - "node": ">=22.13.0", + "node": "^22.18.0 || >=24.3.0", "pnpm": ">=9.0.0" }, "devEngines": { diff --git a/tests/pools/abstract-pool.test.mjs b/tests/pools/abstract-pool.test.mjs index 8056b143f..16a107e5f 100644 --- a/tests/pools/abstract-pool.test.mjs +++ b/tests/pools/abstract-pool.test.mjs @@ -106,7 +106,7 @@ describe('Abstract pool test suite', () => { it('Verify that a negative number of workers is checked', () => { expect( () => - new FixedClusterPool(-1, './tests/worker-files/cluster/testWorker.cjs') + new FixedClusterPool(-1, './tests/worker-files/cluster/testWorker.mjs') ).toThrow( new RangeError( 'Cannot instantiate a pool with a negative number of workers' @@ -147,7 +147,7 @@ describe('Abstract pool test suite', () => { new DynamicClusterPool( 1, undefined, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) ).toThrow( new TypeError( @@ -171,7 +171,7 @@ describe('Abstract pool test suite', () => { new DynamicClusterPool( 0, 0.5, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) ).toThrow( new TypeError( @@ -207,7 +207,7 @@ describe('Abstract pool test suite', () => { new DynamicClusterPool( 1, 1, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) ).toThrow( new RangeError( @@ -882,7 +882,7 @@ describe('Abstract pool test suite', () => { pool = new DynamicClusterPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) expect(pool.info).toStrictEqual({ busyWorkerNodes: 0, @@ -908,7 +908,7 @@ describe('Abstract pool test suite', () => { it('Verify that pool worker tasks usage are initialized', async () => { const pool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) for (const workerNode of pool.workerNodes) { expect(workerNode).toBeInstanceOf(WorkerNode) @@ -944,7 +944,7 @@ describe('Abstract pool test suite', () => { it('Verify that pool worker tasks queue are initialized', async () => { let pool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) for (const workerNode of pool.workerNodes) { expect(workerNode).toBeInstanceOf(WorkerNode) @@ -974,7 +974,7 @@ describe('Abstract pool test suite', () => { it('Verify that pool worker info are initialized', async () => { let pool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) for (const workerNode of pool.workerNodes) { expect(workerNode).toBeInstanceOf(WorkerNode) @@ -1036,7 +1036,7 @@ describe('Abstract pool test suite', () => { it('Verify that pool can be started after initialization', async () => { const pool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', { startWorkers: false, } @@ -1064,7 +1064,7 @@ describe('Abstract pool test suite', () => { it('Verify that pool execute() arguments are checked', async () => { const pool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) await expect(pool.execute(undefined, 0)).rejects.toThrow( new TypeError('name argument must be a string') @@ -1090,7 +1090,7 @@ describe('Abstract pool test suite', () => { it('Verify that pool worker tasks usage are computed', async () => { const pool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) const promises = new Set() const maxMultiplier = 2 @@ -1237,7 +1237,7 @@ describe('Abstract pool test suite', () => { const pool = new DynamicClusterPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) expect(pool.emitter.eventNames()).toStrictEqual([]) let poolInfo @@ -1341,7 +1341,7 @@ describe('Abstract pool test suite', () => { const pool = new DynamicClusterPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) expect(pool.emitter.eventNames()).toStrictEqual([]) const promises = new Set() @@ -1495,7 +1495,7 @@ describe('Abstract pool test suite', () => { const pool = new DynamicClusterPool( 0, numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) expect(pool.emitter.eventNames()).toStrictEqual([]) const promises = new Set() @@ -1568,7 +1568,7 @@ describe('Abstract pool test suite', () => { for (const { PoolClass, workerFilePath, workerType } of [ { PoolClass: FixedClusterPool, - workerFilePath: './tests/worker-files/cluster/asyncWorker.cjs', + workerFilePath: './tests/worker-files/cluster/asyncWorker.mjs', workerType: WorkerTypes.cluster, }, { @@ -1659,7 +1659,7 @@ describe('Abstract pool test suite', () => { await dynamicThreadPool.destroy() const fixedClusterPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs' + './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs' ) await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1) expect(fixedClusterPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true) @@ -2081,7 +2081,7 @@ describe('Abstract pool test suite', () => { await dynamicThreadPool.destroy() const fixedClusterPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs' + './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs' ) await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1) expect(fixedClusterPool.listTaskFunctionsProperties()).toStrictEqual([ @@ -2151,7 +2151,7 @@ describe('Abstract pool test suite', () => { const pool = new DynamicClusterPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, - './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs' + './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs' ) const data = { n: 10 } const result0 = await pool.execute(data) @@ -2381,7 +2381,7 @@ describe('Abstract pool test suite', () => { const pool = new DynamicClusterPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) const workerNodeKey = 0 await expect( @@ -2394,7 +2394,7 @@ describe('Abstract pool test suite', () => { const pool = new DynamicClusterPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) const workerNodeKey = 0 await expect( @@ -2418,7 +2418,7 @@ describe('Abstract pool test suite', () => { const pool = new DynamicClusterPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) await expect( pool.sendTaskFunctionOperationToWorkers({ diff --git a/tests/pools/cluster/dynamic.test.mjs b/tests/pools/cluster/dynamic.test.mjs index 45f2be517..d057dfd6d 100644 --- a/tests/pools/cluster/dynamic.test.mjs +++ b/tests/pools/cluster/dynamic.test.mjs @@ -17,7 +17,7 @@ describe('Dynamic cluster pool test suite', () => { pool = new DynamicClusterPool( min, max, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', { errorHandler: e => console.error(e), } @@ -123,7 +123,7 @@ describe('Dynamic cluster pool test suite', () => { const longRunningPool = new DynamicClusterPool( min, max, - './tests/worker-files/cluster/longRunningWorkerHardBehavior.cjs', + './tests/worker-files/cluster/longRunningWorkerHardBehavior.mjs', { errorHandler: e => console.error(e), exitHandler: () => console.info('long executing worker exited'), @@ -150,7 +150,7 @@ describe('Dynamic cluster pool test suite', () => { const longRunningPool = new DynamicClusterPool( min, max, - './tests/worker-files/cluster/longRunningWorkerSoftBehavior.cjs', + './tests/worker-files/cluster/longRunningWorkerSoftBehavior.mjs', { errorHandler: e => console.error(e), exitHandler: () => console.info('long executing worker exited'), @@ -173,7 +173,7 @@ describe('Dynamic cluster pool test suite', () => { const pool = new DynamicClusterPool( 0, max, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) expect(pool).toBeInstanceOf(DynamicClusterPool) // We need to clean up the resources after our test @@ -185,7 +185,7 @@ describe('Dynamic cluster pool test suite', () => { const pool = new DynamicClusterPool( 0, max, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', { startWorkers: false, workerChoiceStrategy, diff --git a/tests/pools/cluster/fixed.test.mjs b/tests/pools/cluster/fixed.test.mjs index 9c40ab1bb..481a6de8e 100644 --- a/tests/pools/cluster/fixed.test.mjs +++ b/tests/pools/cluster/fixed.test.mjs @@ -14,14 +14,14 @@ describe('Fixed cluster pool test suite', () => { beforeAll(() => { pool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', { errorHandler: e => console.error(e), } ) queuePool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', { enableTasksQueue: true, errorHandler: e => console.error(e), @@ -32,30 +32,30 @@ describe('Fixed cluster pool test suite', () => { ) emptyPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/emptyWorker.cjs', + './tests/worker-files/cluster/emptyWorker.mjs', { exitHandler: () => console.info('empty pool worker exited') } ) echoPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/echoWorker.cjs' + './tests/worker-files/cluster/echoWorker.mjs' ) errorPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/errorWorker.cjs', + './tests/worker-files/cluster/errorWorker.mjs', { errorHandler: e => console.error(e), } ) asyncErrorPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/asyncErrorWorker.cjs', + './tests/worker-files/cluster/asyncErrorWorker.mjs', { errorHandler: e => console.error(e), } ) asyncPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/asyncWorker.cjs' + './tests/worker-files/cluster/asyncWorker.mjs' ) }) @@ -294,7 +294,7 @@ describe('Fixed cluster pool test suite', () => { }) it('Verify that cluster pool options are checked', async () => { - const workerFilePath = './tests/worker-files/cluster/testWorker.cjs' + const workerFilePath = './tests/worker-files/cluster/testWorker.mjs' let pool = new FixedClusterPool(numberOfWorkers, workerFilePath) expect(pool.opts.env).toBeUndefined() expect(pool.opts.settings).toBeUndefined() @@ -321,7 +321,7 @@ describe('Fixed cluster pool test suite', () => { }) it('Verify destroyWorkerNode()', async () => { - const workerFilePath = './tests/worker-files/cluster/testWorker.cjs' + const workerFilePath = './tests/worker-files/cluster/testWorker.mjs' const pool = new FixedClusterPool(numberOfWorkers, workerFilePath) const workerNodeKey = 0 let disconnectEvent = 0 @@ -344,7 +344,7 @@ describe('Fixed cluster pool test suite', () => { it('Verify that a pool with zero worker fails', () => { expect( () => - new FixedClusterPool(0, './tests/worker-files/cluster/testWorker.cjs') + new FixedClusterPool(0, './tests/worker-files/cluster/testWorker.mjs') ).toThrow('Cannot instantiate a fixed pool with zero worker') }) }) diff --git a/tests/pools/cluster/module-formats.test.mjs b/tests/pools/cluster/module-formats.test.mjs new file mode 100644 index 000000000..617ec16be --- /dev/null +++ b/tests/pools/cluster/module-formats.test.mjs @@ -0,0 +1,70 @@ +import { describe, expect, it } from 'vitest' + +import { DynamicClusterPool, FixedClusterPool } from '../../../lib/index.mjs' + +const bounded = async promise => { + let timeout + try { + return await Promise.race([ + promise, + new Promise((resolve, reject) => { + timeout = setTimeout( + () => reject(new Error('Cluster worker operation remained pending')), + 5000 + ) + }), + ]) + } finally { + clearTimeout(timeout) + } +} + +// Start destruction before force-killing on failure, so fixed workers cannot restart. +const destroyPool = async pool => { + const workers = pool.workerNodes.map(workerNode => workerNode.worker) + const exits = workers.map(worker => { + return worker.isDead() + ? Promise.resolve() + : new Promise(resolve => worker.once('exit', resolve)) + }) + try { + await bounded(pool.destroy()) + expect(workers.every(worker => worker.isDead())).toBe(true) + } finally { + for (const worker of workers) { + if (!worker.isDead()) worker.process.kill('SIGKILL') + } + await bounded(Promise.all(exits)) + } + expect(workers).toHaveLength(1) + expect(pool.info.started).toBe(false) +} + +for (const [poolType, PoolClass, sizes] of [ + ['fixed', FixedClusterPool, [1]], + ['dynamic', DynamicClusterPool, [0, 1]], +]) { + describe(`${poolType} cluster worker module formats`, { retry: 0 }, () => { + for (const [format, workerFile] of [ + ['ESM', './tests/worker-files/cluster/echoWorker.mjs'], + ['CommonJS', './tests/worker-files/cluster/echoWorker.cjs'], + ]) { + it(`executes an immediate task with ${format} and destroys the worker`, async () => { + const pool = new PoolClass(...sizes, workerFile, { + restartWorkerOnError: false, + }) + const data = { + format, + nested: { enabled: true, values: [1, 'two', null] }, + poolType, + } + try { + // Do not wait for online or ready: the first startup message must survive ESM loading. + expect(await bounded(pool.execute(data))).toStrictEqual(data) + } finally { + await destroyPool(pool) + } + }, 20000) + } + }) +} diff --git a/tests/pools/prototype-pollution.test.mjs b/tests/pools/prototype-pollution.test.mjs index e1200ea8f..bec32b0ff 100644 --- a/tests/pools/prototype-pollution.test.mjs +++ b/tests/pools/prototype-pollution.test.mjs @@ -13,9 +13,9 @@ import { FixedThreadPool, } from '../../lib/index.mjs' -const clusterWorker = './tests/worker-files/cluster/testWorker.cjs' +const clusterWorker = './tests/worker-files/cluster/testWorker.mjs' const clusterIntrospectionWorker = resolve( - './tests/worker-files/cluster/prototypePollutionWorker.cjs' + './tests/worker-files/cluster/prototypePollutionWorker.mjs' ) const environmentPollutionKey = 'POOLIFIER_ARBITRARY_ENV_POLLUTION' const pollutedProperties = [ diff --git a/tests/pools/selection-strategies/selection-strategies-utils.test.mjs b/tests/pools/selection-strategies/selection-strategies-utils.test.mjs index 33a3425d1..840b31808 100644 --- a/tests/pools/selection-strategies/selection-strategies-utils.test.mjs +++ b/tests/pools/selection-strategies/selection-strategies-utils.test.mjs @@ -14,7 +14,7 @@ describe('Selection strategies utils test suite', () => { beforeAll(() => { clusterFixedPool = new FixedClusterPool( numberOfWorkers, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) threadFixedPool = new FixedThreadPool( numberOfThreads, diff --git a/tests/pools/selection-strategies/selection-strategies.test.mjs b/tests/pools/selection-strategies/selection-strategies.test.mjs index df69f2f66..56dd2dd9a 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.mjs +++ b/tests/pools/selection-strategies/selection-strategies.test.mjs @@ -77,7 +77,7 @@ describe('Selection strategies test suite', () => { const pool = new DynamicClusterPool( min, max, - './tests/worker-files/cluster/testWorker.cjs' + './tests/worker-files/cluster/testWorker.mjs' ) pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy) @@ -360,7 +360,7 @@ describe('Selection strategies test suite', () => { const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN let pool = new FixedClusterPool( max, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', { workerChoiceStrategy } ) let results = new Set() diff --git a/tests/pools/utils.test.mjs b/tests/pools/utils.test.mjs index 0c5a56e01..35250b0fe 100644 --- a/tests/pools/utils.test.mjs +++ b/tests/pools/utils.test.mjs @@ -678,7 +678,7 @@ parentPort.postMessage({ expect( createWorker( WorkerTypes.cluster, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', {} ) ).toBeInstanceOf(ClusterWorker) @@ -705,7 +705,7 @@ parentPort.postMessage({ }) const clusterWorker = createWorker( WorkerTypes.cluster, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', {} ) const clusterWorkerInfo = initWorkerInfo(clusterWorker) diff --git a/tests/pools/worker-exit.test.mjs b/tests/pools/worker-exit.test.mjs index b521d1610..07bbbe48c 100644 --- a/tests/pools/worker-exit.test.mjs +++ b/tests/pools/worker-exit.test.mjs @@ -49,7 +49,7 @@ const cleanupRegressionPool = async (pool, capturedNodes) => { for (const [workerType, PoolClass, workerFile] of [ ['thread', FixedThreadPool, './tests/worker-files/thread/crashWorker.mjs'], - ['cluster', FixedClusterPool, './tests/worker-files/cluster/crashWorker.cjs'], + ['cluster', FixedClusterPool, './tests/worker-files/cluster/crashWorker.mjs'], ]) { describe(`${workerType} worker exit`, { retry: 0 }, () => { const createPool = async (size = 1, options = {}) => { diff --git a/tests/pools/worker-node.test.mjs b/tests/pools/worker-node.test.mjs index 1e9443da9..4e0a8f16c 100644 --- a/tests/pools/worker-node.test.mjs +++ b/tests/pools/worker-node.test.mjs @@ -26,7 +26,7 @@ describe('Worker node test suite', () => { ) clusterWorkerNode = new WorkerNode( WorkerTypes.cluster, - './tests/worker-files/cluster/testWorker.cjs', + './tests/worker-files/cluster/testWorker.mjs', { tasksQueueBackPressureSize: 12, tasksQueueBucketSize: 6, @@ -83,13 +83,13 @@ describe('Worker node test suite', () => { it('terminates an already disconnected cluster worker node and can terminate it again after exit', async () => { const clusterSettings = { ...cluster.settings } cluster.setupPrimary({ - exec: './tests/worker-files/cluster/crashWorker.cjs', + exec: './tests/worker-files/cluster/crashWorker.mjs', }) let workerNode try { workerNode = new WorkerNode( WorkerTypes.cluster, - './tests/worker-files/cluster/crashWorker.cjs', + './tests/worker-files/cluster/crashWorker.mjs', { tasksQueueBackPressureSize: 12, tasksQueueBucketSize: 6, diff --git a/tests/worker-files/cluster/asyncErrorWorker.cjs b/tests/worker-files/cluster/asyncErrorWorker.mjs similarity index 66% rename from tests/worker-files/cluster/asyncErrorWorker.cjs rename to tests/worker-files/cluster/asyncErrorWorker.mjs index ffab9c176..d9bae1e57 100644 --- a/tests/worker-files/cluster/asyncErrorWorker.cjs +++ b/tests/worker-files/cluster/asyncErrorWorker.mjs @@ -1,6 +1,5 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') -const { sleepTaskFunction } = require('../../test-utils.cjs') +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' +import { sleepTaskFunction } from '../../test-utils.cjs' /** * Test worker function that throws an error after sleeping. @@ -16,7 +15,7 @@ async function error (data) { ) } -module.exports = new ClusterWorker(error, { +export default new ClusterWorker(error, { killBehavior: KillBehaviors.HARD, maxInactiveTime: 500, }) diff --git a/tests/worker-files/cluster/asyncWorker.cjs b/tests/worker-files/cluster/asyncWorker.mjs similarity index 58% rename from tests/worker-files/cluster/asyncWorker.cjs rename to tests/worker-files/cluster/asyncWorker.mjs index 1ebe9a5e3..f642bd7e7 100644 --- a/tests/worker-files/cluster/asyncWorker.cjs +++ b/tests/worker-files/cluster/asyncWorker.mjs @@ -1,6 +1,5 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') -const { sleepTaskFunction } = require('../../test-utils.cjs') +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' +import { sleepTaskFunction } from '../../test-utils.cjs' /** * Test worker function that sleeps for a specified duration. @@ -11,7 +10,7 @@ async function sleep (data) { return sleepTaskFunction(data, 2000) } -module.exports = new ClusterWorker(sleep, { +export default new ClusterWorker(sleep, { killBehavior: KillBehaviors.HARD, maxInactiveTime: 500, }) diff --git a/tests/worker-files/cluster/crashWorker.cjs b/tests/worker-files/cluster/crashWorker.mjs similarity index 85% rename from tests/worker-files/cluster/crashWorker.cjs rename to tests/worker-files/cluster/crashWorker.mjs index 56e6e4bf8..634a5faba 100644 --- a/tests/worker-files/cluster/crashWorker.cjs +++ b/tests/worker-files/cluster/crashWorker.mjs @@ -1,7 +1,6 @@ -'use strict' -const cluster = require('node:cluster') +import cluster from 'node:cluster' -const { ClusterWorker } = require('../../../lib/index.cjs') +import { ClusterWorker } from '../../../lib/index.mjs' const pendingTasks = new Map() @@ -24,7 +23,7 @@ process.on('message', message => { } }) -module.exports = new ClusterWorker(async data => { +export default new ClusterWorker(async data => { if (data.exitCode != null) { // Exit without an error event to exercise lost task responses. // eslint-disable-next-line n/no-process-exit diff --git a/tests/worker-files/cluster/echoWorker.mjs b/tests/worker-files/cluster/echoWorker.mjs new file mode 100644 index 000000000..4906c7ee4 --- /dev/null +++ b/tests/worker-files/cluster/echoWorker.mjs @@ -0,0 +1,14 @@ +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' + +/** + * Test worker function that echoes the input data. + * @param data - The task data to echo. + * @returns The same data that was passed in. + */ +function echo (data) { + return data +} + +export default new ClusterWorker(echo, { + killBehavior: KillBehaviors.HARD, +}) diff --git a/tests/worker-files/cluster/emptyWorker.cjs b/tests/worker-files/cluster/emptyWorker.cjs deleted file mode 100644 index 78f534ab8..000000000 --- a/tests/worker-files/cluster/emptyWorker.cjs +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') - -/** - * - */ -function test () {} - -module.exports = new ClusterWorker(test, { - killBehavior: KillBehaviors.HARD, - maxInactiveTime: 500, -}) diff --git a/tests/worker-files/cluster/emptyWorker.mjs b/tests/worker-files/cluster/emptyWorker.mjs new file mode 100644 index 000000000..eb05acfa8 --- /dev/null +++ b/tests/worker-files/cluster/emptyWorker.mjs @@ -0,0 +1,11 @@ +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' + +/** + * + */ +function test () {} + +export default new ClusterWorker(test, { + killBehavior: KillBehaviors.HARD, + maxInactiveTime: 500, +}) diff --git a/tests/worker-files/cluster/errorWorker.cjs b/tests/worker-files/cluster/errorWorker.mjs similarity index 53% rename from tests/worker-files/cluster/errorWorker.cjs rename to tests/worker-files/cluster/errorWorker.mjs index 9a2695b25..0828169b5 100644 --- a/tests/worker-files/cluster/errorWorker.cjs +++ b/tests/worker-files/cluster/errorWorker.mjs @@ -1,5 +1,4 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' /** * @@ -8,7 +7,7 @@ function error () { throw new Error('Error Message from ClusterWorker') } -module.exports = new ClusterWorker(error, { +export default new ClusterWorker(error, { killBehavior: KillBehaviors.HARD, maxInactiveTime: 500, }) diff --git a/tests/worker-files/cluster/longRunningWorkerHardBehavior.cjs b/tests/worker-files/cluster/longRunningWorkerHardBehavior.mjs similarity index 59% rename from tests/worker-files/cluster/longRunningWorkerHardBehavior.cjs rename to tests/worker-files/cluster/longRunningWorkerHardBehavior.mjs index eb31dfa3d..83d4ac67a 100644 --- a/tests/worker-files/cluster/longRunningWorkerHardBehavior.cjs +++ b/tests/worker-files/cluster/longRunningWorkerHardBehavior.mjs @@ -1,6 +1,5 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') -const { sleepTaskFunction } = require('../../test-utils.cjs') +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' +import { sleepTaskFunction } from '../../test-utils.cjs' /** * Test worker function for long-running tasks with hard kill behavior. @@ -11,7 +10,7 @@ async function sleep (data) { return sleepTaskFunction(data, 50000) } -module.exports = new ClusterWorker(sleep, { +export default new ClusterWorker(sleep, { killBehavior: KillBehaviors.HARD, maxInactiveTime: 500, }) diff --git a/tests/worker-files/cluster/longRunningWorkerSoftBehavior.cjs b/tests/worker-files/cluster/longRunningWorkerSoftBehavior.mjs similarity index 60% rename from tests/worker-files/cluster/longRunningWorkerSoftBehavior.cjs rename to tests/worker-files/cluster/longRunningWorkerSoftBehavior.mjs index 94ad584f2..4052bfe48 100644 --- a/tests/worker-files/cluster/longRunningWorkerSoftBehavior.cjs +++ b/tests/worker-files/cluster/longRunningWorkerSoftBehavior.mjs @@ -1,6 +1,5 @@ -'use strict' -const { ClusterWorker } = require('../../../lib/index.cjs') -const { sleepTaskFunction } = require('../../test-utils.cjs') +import { ClusterWorker } from '../../../lib/index.mjs' +import { sleepTaskFunction } from '../../test-utils.cjs' /** * Test worker function that performs a long-running sleep operation with soft behavior. @@ -11,6 +10,6 @@ async function sleep (data) { return sleepTaskFunction(data, 50000) } -module.exports = new ClusterWorker(sleep, { +export default new ClusterWorker(sleep, { maxInactiveTime: 500, }) diff --git a/tests/worker-files/cluster/prototypePollutionWorker.cjs b/tests/worker-files/cluster/prototypePollutionWorker.mjs similarity index 75% rename from tests/worker-files/cluster/prototypePollutionWorker.cjs rename to tests/worker-files/cluster/prototypePollutionWorker.mjs index 08bef924e..e9fee840f 100644 --- a/tests/worker-files/cluster/prototypePollutionWorker.cjs +++ b/tests/worker-files/cluster/prototypePollutionWorker.mjs @@ -1,5 +1,4 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' /** * Returns the cluster worker launch context needed by security regressions. @@ -15,7 +14,7 @@ function inspectLaunchContext (data = {}) { } } -module.exports = new ClusterWorker(inspectLaunchContext, { +export default new ClusterWorker(inspectLaunchContext, { killBehavior: KillBehaviors.HARD, maxInactiveTime: 500, }) diff --git a/tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs b/tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs similarity index 72% rename from tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs rename to tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs index 3ce4f7c53..0085d50c5 100644 --- a/tests/worker-files/cluster/testMultipleTaskFunctionsWorker.cjs +++ b/tests/worker-files/cluster/testMultipleTaskFunctionsWorker.mjs @@ -1,12 +1,11 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') -const { +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' +import { factorial, fibonacci, jsonIntegerSerialization, -} = require('../../test-utils.cjs') +} from '../../test-utils.cjs' -module.exports = new ClusterWorker( +export default new ClusterWorker( { factorial: { priority: 1, diff --git a/tests/worker-files/cluster/testTaskFunctionObjectsWorker.cjs b/tests/worker-files/cluster/testTaskFunctionObjectsWorker.mjs similarity index 68% rename from tests/worker-files/cluster/testTaskFunctionObjectsWorker.cjs rename to tests/worker-files/cluster/testTaskFunctionObjectsWorker.mjs index 265ea136c..961c3b7cd 100644 --- a/tests/worker-files/cluster/testTaskFunctionObjectsWorker.cjs +++ b/tests/worker-files/cluster/testTaskFunctionObjectsWorker.mjs @@ -1,12 +1,11 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') -const { +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' +import { factorial, fibonacci, jsonIntegerSerialization, -} = require('../../test-utils.cjs') +} from '../../test-utils.cjs' -module.exports = new ClusterWorker( +export default new ClusterWorker( { factorial: { taskFunction: data => factorial(data.n) }, fibonacci: { priority: -5, taskFunction: data => fibonacci(data.n) }, diff --git a/tests/worker-files/cluster/testWorker.cjs b/tests/worker-files/cluster/testWorker.mjs similarity index 62% rename from tests/worker-files/cluster/testWorker.cjs rename to tests/worker-files/cluster/testWorker.mjs index 871f74d09..0bc4a09de 100644 --- a/tests/worker-files/cluster/testWorker.cjs +++ b/tests/worker-files/cluster/testWorker.mjs @@ -1,7 +1,6 @@ -'use strict' -const { ClusterWorker, KillBehaviors } = require('../../../lib/index.cjs') -const { TaskFunctions } = require('../../test-types.cjs') -const { executeTaskFunction } = require('../../test-utils.cjs') +import { ClusterWorker, KillBehaviors } from '../../../lib/index.mjs' +import { TaskFunctions } from '../../test-types.cjs' +import { executeTaskFunction } from '../../test-utils.cjs' /** * Test worker function that executes configurable task functions for testing. @@ -14,7 +13,7 @@ function test (data) { return executeTaskFunction(data) } -module.exports = new ClusterWorker(test, { +export default new ClusterWorker(test, { killBehavior: KillBehaviors.HARD, maxInactiveTime: 500, }) -- 2.53.0