'builtins',
'christopher',
'cjs',
+ 'cloneable',
'comparator',
'cpu',
'cpus',
- [workerpool](https://github.com/josdejong/workerpool)
- [worker-nodes](https://github.com/allegro/node-worker-nodes)
- [node-worker-threads-pool](https://github.com/SUCHMOKUO/node-worker-threads-pool)
-- [threads.js](https://github.com/andywer/threads.js/)
-- [threadwork](https://github.com/kevlened/threadwork)
-- [microjob](https://github.com/wilk/microjob)
Those are our results:
<!-- - [node-worker-threads-pool](https://github.com/SUCHMOKUO/node-worker-threads-pool): removed because it does not support dynamic modules import or import outside the worker function. The worker function is expected to be self-contained, which makes it difficult to use in real world application without ugly hacks. -->
- [worker-threads-pool](https://github.com/watson/worker-threads-pool): removed because unmaintained since more than 4 years.
+- [threadwork](https://github.com/kevlened/threadwork): removed because unmaintained since more than 3 years.
+- [microjob](https://github.com/wilk/microjob): removed because unmaintained since more than 5 years.
+- [threads.js](https://github.com/andywer/threads.js/): removed because not a threads pool.
### Internal
const debug = false
-function yourFunction (data) {
+function workerFunction (data) {
data = data || {}
data.function = data.function || WorkerFunctions.jsonIntegerSerialization
executeWorkerFunction(data)
return { ok: 1 }
}
-export default new ClusterWorker(yourFunction)
+export default new ClusterWorker(workerFunction)
const debug = false
-function yourFunction (data) {
+function workerFunction (data) {
data = data || {}
data.function = data.function || WorkerFunctions.jsonIntegerSerialization
executeWorkerFunction(data)
return { ok: 1 }
}
-export default new ThreadWorker(yourFunction)
+export default new ThreadWorker(workerFunction)
+++ /dev/null
-// IMPORT LIBRARIES
-import { job, start } from 'microjob'
-// FINISH IMPORT LIBRARIES
-// IMPORT FUNCTION TO BENCH
-import functionToBench from './functions/function-to-bench.js'
-// FINISH IMPORT FUNCTION TO BENCH
-const size = parseInt(process.env.POOL_SIZE)
-const iterations = parseInt(process.env.NUM_ITERATIONS)
-const data = {
- test: 'MYBENCH',
- taskType: process.env.TASK_TYPE,
- taskSize: parseInt(process.env.TASK_SIZE)
-}
-
-async function run () {
- await start({ maxWorkers: size })
- const promises = []
- for (let i = 0; i < iterations; i++) {
- promises.push(
- job(
- data => {
- functionToBench(data)
- },
- { data, ctx: { functionToBench } }
- )
- )
- }
- await Promise.all(promises)
- // eslint-disable-next-line n/no-process-exit
- process.exit()
-}
-
-await run()
+++ /dev/null
-// IMPORT LIBRARIES
-import threadPool from './pool-threadwork'
-// FINISH IMPORT LIBRARIES
-const iterations = parseInt(process.env.NUM_ITERATIONS)
-const data = {
- test: 'MYBENCH',
- taskType: process.env.TASK_TYPE,
- taskSize: parseInt(process.env.TASK_SIZE)
-}
-
-async function run () {
- const promises = []
- for (let i = 0; i < iterations; i++) {
- promises.push(threadPool.run(data))
- }
- await Promise.all(promises)
- // eslint-disable-next-line n/no-process-exit
- process.exit()
-}
-
-await run()
'node fixed-worker-nodes.js' \
'node dynamic-node-worker-threads-pool.mjs' \
'node static-node-worker-threads-pool.mjs' \
- 'node threadjs.mjs' \
- 'node fixed-threadwork.mjs' \
- 'node fixed-microjob.mjs'
{
"name": "poolifier-benchmarks",
- "version": "1.0.0-internal",
+ "version": "1.0.0",
"description": "This project contains benchmarks for the most used and popular Node.js thread/cluster pools implementations",
"private": true,
"main": "index.js",
},
"volta": {
"node": "18.16.1",
- "pnpm": "8.6.3"
+ "pnpm": "8.6.5"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
- "microjob": "0.7.0",
"node-worker-threads-pool": "1.5.1",
"piscina": "4.0.0",
"poolifier": "2.6.3",
- "threads": "1.7.0",
- "threadwork": "0.6.0",
"tinypool": "0.5.0",
"worker-nodes": "2.6.0",
"workerpool": "6.4.0"
excludeLinksFromLockfile: false
dependencies:
- microjob:
- specifier: 0.7.0
- version: 0.7.0
node-worker-threads-pool:
specifier: 1.5.1
version: 1.5.1
poolifier:
specifier: 2.6.3
version: 2.6.3
- threads:
- specifier: 1.7.0
- version: 1.7.0
- threadwork:
- specifier: 0.6.0
- version: 0.6.0
tinypool:
specifier: 0.5.0
version: 0.5.0
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: false
- /callsites@3.1.0:
- resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
- engines: {node: '>=6'}
- dev: false
-
- /debug@4.3.4:
- resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
- engines: {node: '>=6.0'}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
- dependencies:
- ms: 2.1.2
- dev: false
-
- /esm@3.2.25:
- resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
- engines: {node: '>=6'}
- dev: false
- optional: true
-
/event-lite@0.1.3:
resolution: {integrity: sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==}
dev: false
resolution: {integrity: sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==}
dev: false
- /find-up@5.0.0:
- resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
- engines: {node: '>=10'}
- dependencies:
- locate-path: 6.0.0
- path-exists: 4.0.0
- dev: false
-
/hdr-histogram-js@2.0.3:
resolution: {integrity: sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==}
dependencies:
resolution: {integrity: sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==}
dev: false
- /is-observable@2.1.0:
- resolution: {integrity: sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==}
- engines: {node: '>=8'}
- dev: false
-
/isarray@1.0.0:
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
dev: false
- /locate-path@6.0.0:
- resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
- engines: {node: '>=10'}
- dependencies:
- p-locate: 5.0.0
- dev: false
-
- /microjob@0.7.0:
- resolution: {integrity: sha512-ofDpqaVEv67ymCYdCE8eIVMCJY0H/hAtGxYmi1pXjtNkLOM0UUuUDshA1YLdVFwPwwt5+SW9EbBtSfsNokf+PA==}
- engines: {node: '>=10.5.0', npm: '>= 6.0.0'}
- dev: false
-
- /ms@2.1.2:
- resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
- dev: false
-
/msgpack-lite@0.1.26:
resolution: {integrity: sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==}
hasBin: true
resolution: {integrity: sha512-7TXAhpMm+jO4MfESxYLtMGSnJWv+itdNHMdaFmeZuPXxwFGU90mtEB42BciUULXOUAxYBfXILAuvrSG3rQZ7mw==}
dev: false
- /observable-fns@0.6.1:
- resolution: {integrity: sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==}
- dev: false
-
- /p-limit@3.1.0:
- resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
- engines: {node: '>=10'}
- dependencies:
- yocto-queue: 0.1.0
- dev: false
-
- /p-locate@5.0.0:
- resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
- engines: {node: '>=10'}
- dependencies:
- p-limit: 3.1.0
- dev: false
-
/pako@1.0.11:
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
dev: false
- /path-exists@4.0.0:
- resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
- engines: {node: '>=8'}
- dev: false
-
/piscina@4.0.0:
resolution: {integrity: sha512-641nAmJS4k4iqpNUqfggqUBUMmlw0ZoM5VZKdQkV2e970Inn3Tk9kroCc1wpsYLD07vCwpys5iY0d3xI/9WkTg==}
dependencies:
nice-napi: 1.0.2
dev: false
- /pkg-dir@5.0.0:
- resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
- engines: {node: '>=10'}
- dependencies:
- find-up: 5.0.0
- dev: false
-
/poolifier@2.6.3:
resolution: {integrity: sha512-5kQjBXqeW8dbzlmDxKRvlC6Vi2zBrpiviVb53rupdQWIsivB6waApeJT4ayhVVLqKGrvLVr9HAeBMHBJaNUDVA==}
engines: {node: '>=16.14.0', pnpm: '>=8.6.0'}
requiresBuild: true
dev: false
- /threads@1.7.0:
- resolution: {integrity: sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==}
- dependencies:
- callsites: 3.1.0
- debug: 4.3.4
- is-observable: 2.1.0
- observable-fns: 0.6.1
- optionalDependencies:
- tiny-worker: 2.3.0
- transitivePeerDependencies:
- - supports-color
- dev: false
-
- /threadwork@0.6.0:
- resolution: {integrity: sha512-NzKDArTtcSAq0jlMdiC04+fuls5nWn1ziptmMTBwPyjKxZk+aQvw/LVVf3IW3tUKz4vLGJ2XE+PXDMoJuoNEfQ==}
- engines: {node: '>=12'}
- dependencies:
- callsites: 3.1.0
- pkg-dir: 5.0.0
- dev: false
-
- /tiny-worker@2.3.0:
- resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==}
- requiresBuild: true
- dependencies:
- esm: 3.2.25
- dev: false
- optional: true
-
/tinypool@0.5.0:
resolution: {integrity: sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==}
engines: {node: '>=14.0.0'}
/workerpool@6.4.0:
resolution: {integrity: sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A==}
dev: false
-
- /yocto-queue@0.1.0:
- resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
- engines: {node: '>=10'}
- dev: false
+++ /dev/null
-// IMPORT LIBRARIES
-import { ThreadPool } from 'threadwork'
-// FINISH IMPORT LIBRARIES
-// IMPORT FUNCTION TO BENCH
-import functionToBench from './functions/function-to-bench.js'
-// FINISH IMPORT FUNCTION TO BENCH
-const size = parseInt(process.env.POOL_SIZE)
-
-export default new ThreadPool({ task: functionToBench, size })
+++ /dev/null
-// IMPORT LIBRARIES
-import { Worker, spawn } from 'threads'
-// FINISH IMPORT LIBRARIES
-const size = parseInt(process.env.POOL_SIZE)
-const iterations = parseInt(process.env.NUM_ITERATIONS)
-const data = {
- test: 'MYBENCH',
- taskType: process.env.TASK_TYPE,
- taskSize: parseInt(process.env.TASK_SIZE)
-}
-
-// Threads.js is not really a pool so we need to write few additional code
-const workers = []
-async function poolify () {
- for (let i = 0; i < size; i++) {
- const worker = await spawn(
- new Worker('./workers/threadjs/function-to-bench-worker.mjs')
- )
- workers.push(worker)
- }
-}
-
-async function run () {
- await poolify()
- const promises = []
- for (let i = 0; i < iterations; i++) {
- const worker = workers[i % size]
- promises.push(worker.exposedFunction(data))
- }
- await Promise.all(promises)
- // eslint-disable-next-line n/no-process-exit
- process.exit()
-}
-
-await run()
+++ /dev/null
-import { expose } from 'threads/worker'
-import functionToBench from '../../functions/function-to-bench.js'
-
-expose({
- exposedFunction (data) {
- return functionToBench(data)
- }
-})
},
"volta": {
"node": "20.3.1",
- "pnpm": "8.6.3"
+ "pnpm": "8.6.5"
},
"repository": {
"type": "git",
"@rollup/plugin-terser": "^0.4.3",
"@rollup/plugin-typescript": "^11.1.1",
"@types/node": "^20.3.1",
- "@typescript-eslint/eslint-plugin": "^5.60.0",
- "@typescript-eslint/parser": "^5.60.0",
+ "@typescript-eslint/eslint-plugin": "^5.60.1",
+ "@typescript-eslint/parser": "^5.60.1",
"benny": "^3.7.1",
"c8": "^8.0.0",
"eslint": "^8.43.0",
"eslint-define-config": "^1.21.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
- "eslint-plugin-jsdoc": "^46.2.6",
+ "eslint-plugin-jsdoc": "^46.3.0",
"eslint-plugin-n": "^16.0.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-spellcheck": "^0.0.20",
specifier: ^20.3.1
version: 20.3.1
'@typescript-eslint/eslint-plugin':
- specifier: ^5.60.0
- version: 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
+ specifier: ^5.60.1
+ version: 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
'@typescript-eslint/parser':
- specifier: ^5.60.0
- version: 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ specifier: ^5.60.1
+ version: 5.60.1(eslint@8.43.0)(typescript@5.1.3)
benny:
specifier: ^3.7.1
version: 3.7.1
version: 17.1.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)
eslint-config-standard-with-typescript:
specifier: ^35.0.0
- version: 35.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
+ version: 35.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
eslint-define-config:
specifier: ^1.21.0
version: 1.21.0
eslint-import-resolver-typescript:
specifier: ^3.5.5
- version: 3.5.5(@typescript-eslint/parser@5.60.0)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
+ version: 3.5.5(@typescript-eslint/parser@5.60.1)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
eslint-plugin-import:
specifier: ^2.27.5
- version: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ version: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
eslint-plugin-jsdoc:
- specifier: ^46.2.6
- version: 46.2.6(eslint@8.43.0)
+ specifier: ^46.3.0
+ version: 46.3.0(eslint@8.43.0)
eslint-plugin-n:
specifier: ^16.0.1
version: 16.0.1(eslint@8.43.0)
'@types/yargs-parser': 21.0.0
dev: true
- /@typescript-eslint/eslint-plugin@5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3):
- resolution: {integrity: sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg==}
+ /@typescript-eslint/eslint-plugin@5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3):
+ resolution: {integrity: sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
'@typescript-eslint/parser': ^5.0.0
optional: true
dependencies:
'@eslint-community/regexpp': 4.5.1
- '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
- '@typescript-eslint/scope-manager': 5.60.0
- '@typescript-eslint/type-utils': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
- '@typescript-eslint/utils': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/scope-manager': 5.60.1
+ '@typescript-eslint/type-utils': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/utils': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.43.0
grapheme-splitter: 1.0.4
- supports-color
dev: true
- /@typescript-eslint/parser@5.60.0(eslint@8.43.0)(typescript@5.1.3):
- resolution: {integrity: sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ==}
+ /@typescript-eslint/parser@5.60.1(eslint@8.43.0)(typescript@5.1.3):
+ resolution: {integrity: sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
typescript:
optional: true
dependencies:
- '@typescript-eslint/scope-manager': 5.60.0
- '@typescript-eslint/types': 5.60.0
- '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3)
+ '@typescript-eslint/scope-manager': 5.60.1
+ '@typescript-eslint/types': 5.60.1
+ '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3)
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.43.0
typescript: 5.1.3
- supports-color
dev: true
- /@typescript-eslint/scope-manager@5.60.0:
- resolution: {integrity: sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ==}
+ /@typescript-eslint/scope-manager@5.60.1:
+ resolution: {integrity: sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
- '@typescript-eslint/types': 5.60.0
- '@typescript-eslint/visitor-keys': 5.60.0
+ '@typescript-eslint/types': 5.60.1
+ '@typescript-eslint/visitor-keys': 5.60.1
dev: true
- /@typescript-eslint/type-utils@5.60.0(eslint@8.43.0)(typescript@5.1.3):
- resolution: {integrity: sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g==}
+ /@typescript-eslint/type-utils@5.60.1(eslint@8.43.0)(typescript@5.1.3):
+ resolution: {integrity: sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: '*'
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3)
- '@typescript-eslint/utils': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3)
+ '@typescript-eslint/utils': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
debug: 4.3.4(supports-color@8.1.1)
eslint: 8.43.0
tsutils: 3.21.0(typescript@5.1.3)
- supports-color
dev: true
- /@typescript-eslint/types@5.60.0:
- resolution: {integrity: sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA==}
+ /@typescript-eslint/types@5.60.1:
+ resolution: {integrity: sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
- /@typescript-eslint/typescript-estree@5.60.0(typescript@5.1.3):
- resolution: {integrity: sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ==}
+ /@typescript-eslint/typescript-estree@5.60.1(typescript@5.1.3):
+ resolution: {integrity: sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
typescript: '*'
typescript:
optional: true
dependencies:
- '@typescript-eslint/types': 5.60.0
- '@typescript-eslint/visitor-keys': 5.60.0
+ '@typescript-eslint/types': 5.60.1
+ '@typescript-eslint/visitor-keys': 5.60.1
debug: 4.3.4(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
- supports-color
dev: true
- /@typescript-eslint/utils@5.60.0(eslint@8.43.0)(typescript@5.1.3):
- resolution: {integrity: sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ==}
+ /@typescript-eslint/utils@5.60.1(eslint@8.43.0)(typescript@5.1.3):
+ resolution: {integrity: sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
'@eslint-community/eslint-utils': 4.4.0(eslint@8.43.0)
'@types/json-schema': 7.0.12
'@types/semver': 7.5.0
- '@typescript-eslint/scope-manager': 5.60.0
- '@typescript-eslint/types': 5.60.0
- '@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3)
+ '@typescript-eslint/scope-manager': 5.60.1
+ '@typescript-eslint/types': 5.60.1
+ '@typescript-eslint/typescript-estree': 5.60.1(typescript@5.1.3)
eslint: 8.43.0
eslint-scope: 5.1.1
semver: 7.5.3
- typescript
dev: true
- /@typescript-eslint/visitor-keys@5.60.0:
- resolution: {integrity: sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw==}
+ /@typescript-eslint/visitor-keys@5.60.1:
+ resolution: {integrity: sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
- '@typescript-eslint/types': 5.60.0
+ '@typescript-eslint/types': 5.60.1
eslint-visitor-keys: 3.4.1
dev: true
eslint-plugin-react: 7.32.2(eslint@8.43.0)
dev: true
- /eslint-config-standard-with-typescript@23.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
+ /eslint-config-standard-with-typescript@23.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
resolution: {integrity: sha512-iaaWifImn37Z1OXbNW1es7KI+S7D408F9ys0bpaQf2temeBWlvb0Nc5qHkOgYaRb5QxTZT32GGeN1gtswASOXA==}
peerDependencies:
'@typescript-eslint/eslint-plugin': ^5.0.0
eslint-plugin-promise: ^6.0.0
typescript: '*'
dependencies:
- '@typescript-eslint/eslint-plugin': 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
- '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/eslint-plugin': 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
eslint: 8.43.0
eslint-config-standard: 17.0.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)
- eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
eslint-plugin-n: 15.7.0(eslint@8.43.0)
eslint-plugin-promise: 6.1.1(eslint@8.43.0)
typescript: 5.1.3
- supports-color
dev: true
- /eslint-config-standard-with-typescript@35.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
+ /eslint-config-standard-with-typescript@35.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3):
resolution: {integrity: sha512-Xa7DY9GgduZyp0qmXxBF0/dB+Vm4/DgWu1lGpNLJV2d46aCaUxTKDEnkzjUWX/1O9S0a+Dhnw7A4oI0JpYzwtw==}
peerDependencies:
'@typescript-eslint/eslint-plugin': ^5.50.0
eslint-plugin-promise: ^6.0.0
typescript: '*'
dependencies:
- '@typescript-eslint/eslint-plugin': 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
- '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/eslint-plugin': 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
eslint: 8.43.0
eslint-config-standard: 17.0.0(eslint-plugin-import@2.27.5)(eslint-plugin-n@16.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)
- eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
eslint-plugin-n: 16.0.1(eslint@8.43.0)
eslint-plugin-promise: 6.1.1(eslint@8.43.0)
typescript: 5.1.3
eslint-plugin-promise: ^6.0.0
dependencies:
eslint: 8.43.0
- eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
eslint-plugin-n: 15.7.0(eslint@8.43.0)
eslint-plugin-promise: 6.1.1(eslint@8.43.0)
dev: true
eslint-plugin-promise: ^6.0.0
dependencies:
eslint: 8.43.0
- eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
eslint-plugin-n: 16.0.1(eslint@8.43.0)
eslint-plugin-promise: 6.1.1(eslint@8.43.0)
dev: true
eslint-plugin-promise: ^6.0.0
dependencies:
eslint: 8.43.0
- eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
eslint-plugin-n: 16.0.1(eslint@8.43.0)
eslint-plugin-promise: 6.1.1(eslint@8.43.0)
dev: true
- supports-color
dev: true
- /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.60.0)(eslint-plugin-import@2.27.5)(eslint@8.43.0):
+ /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.60.1)(eslint-plugin-import@2.27.5)(eslint@8.43.0):
resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
debug: 4.3.4(supports-color@8.1.1)
enhanced-resolve: 5.15.0
eslint: 8.43.0
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
- eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
get-tsconfig: 4.6.0
globby: 13.2.0
is-core-module: 2.12.1
- supports-color
dev: true
- /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
+ /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
engines: {node: '>=4'}
peerDependencies:
eslint-import-resolver-webpack:
optional: true
dependencies:
- '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
debug: 3.2.7
eslint: 8.43.0
eslint-import-resolver-node: 0.3.7
- eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.60.0)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
+ eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.60.1)(eslint-plugin-import@2.27.5)(eslint@8.43.0)
transitivePeerDependencies:
- supports-color
dev: true
regexpp: 3.2.0
dev: true
- /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
+ /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0):
resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
engines: {node: '>=4'}
peerDependencies:
'@typescript-eslint/parser':
optional: true
dependencies:
- '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
array-includes: 3.1.6
array.prototype.flat: 1.3.1
array.prototype.flatmap: 1.3.1
doctrine: 2.1.0
eslint: 8.43.0
eslint-import-resolver-node: 0.3.7
- eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
has: 1.0.3
is-core-module: 2.12.1
is-glob: 4.0.3
- supports-color
dev: true
- /eslint-plugin-jsdoc@46.2.6(eslint@8.43.0):
- resolution: {integrity: sha512-zIaK3zbSrKuH12bP+SPybPgcHSM6MFzh3HFeaODzmsF1N8C1l8dzJ22cW1aq4g0+nayU1VMjmNf7hg0dpShLrA==}
+ /eslint-plugin-jsdoc@46.3.0(eslint@8.43.0):
+ resolution: {integrity: sha512-nfSvsR8YJRZyKrWwcXPSQyQC8jllfdEjcRhTXFr7RxfB5Wyl7AxrfjCUz72WwalkXMF4u+R6F/oDoW46ah69HQ==}
engines: {node: '>=16'}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
peerDependencies:
typescript: '*'
dependencies:
- '@typescript-eslint/eslint-plugin': 5.60.0(@typescript-eslint/parser@5.60.0)(eslint@8.43.0)(typescript@5.1.3)
- '@typescript-eslint/parser': 5.60.0(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/eslint-plugin': 5.60.1(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.3)
+ '@typescript-eslint/parser': 5.60.1(eslint@8.43.0)(typescript@5.1.3)
eslint: 8.43.0
eslint-config-standard-jsx: 11.0.0(eslint-plugin-react@7.32.2)(eslint@8.43.0)
- eslint-config-standard-with-typescript: 23.0.0(@typescript-eslint/eslint-plugin@5.60.0)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
- eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
+ eslint-config-standard-with-typescript: 23.0.0(@typescript-eslint/eslint-plugin@5.60.1)(eslint-plugin-import@2.27.5)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.43.0)(typescript@5.1.3)
+ eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0)
eslint-plugin-n: 15.7.0(eslint@8.43.0)
eslint-plugin-promise: 6.1.1(eslint@8.43.0)
eslint-plugin-react: 7.32.2(eslint@8.43.0)
} from './pools/selection-strategies/selection-strategies-types'
export type { WorkerChoiceStrategyContext } from './pools/selection-strategies/worker-choice-strategy-context'
export { DynamicThreadPool } from './pools/thread/dynamic'
-export {
- FixedThreadPool,
- type ThreadPoolOptions,
- type ThreadWorkerWithMessageChannel
-} from './pools/thread/fixed'
+export { FixedThreadPool, type ThreadPoolOptions } from './pools/thread/fixed'
export type { AbstractWorker } from './worker/abstract-worker'
export { ClusterWorker } from './worker/cluster-worker'
export { ThreadWorker } from './worker/thread-worker'
WorkerSyncFunction
} from './worker/worker-functions'
export type {
- Draft,
MessageValue,
PromiseResponseWrapper,
TaskError,
type TasksQueueOptions,
type WorkerType
} from './pool'
-import type { IWorker, Task, WorkerNode, WorkerUsage } from './worker'
+import type {
+ IWorker,
+ MessageHandler,
+ Task,
+ WorkerNode,
+ WorkerUsage
+} from './worker'
import {
Measurements,
WorkerChoiceStrategies,
* Base class that implements some shared logic for all poolifier pools.
*
* @typeParam Worker - Type of worker which manages this pool.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export abstract class AbstractPool<
Worker extends IWorker,
* @param worker - The worker which should register a listener.
* @param listener - The message listener callback.
*/
- protected abstract registerWorkerMessageListener<
- Message extends Data | Response
- >(worker: Worker, listener: (message: MessageValue<Message>) => void): void
+ private registerWorkerMessageListener<Message extends Data | Response>(
+ worker: Worker,
+ listener: (message: MessageValue<Message>) => void
+ ): void {
+ worker.on('message', listener as MessageHandler<Worker>)
+ }
/**
* Creates a new worker.
/**
* Function that can be hooked up when a worker has been newly created and moved to the pool worker nodes.
*
- * Can be used to update the `maxListeners` or binding the `main-worker`\<-\>`worker` connection if not bind by default.
- *
* @param worker - The newly created worker.
*/
- protected abstract afterWorkerSetup (worker: Worker): void
+ private afterWorkerSetup (worker: Worker): void {
+ // Listen to worker messages.
+ this.registerWorkerMessageListener(worker, this.workerListener())
+ }
/**
* Creates a new worker and sets it up completely in the pool worker nodes.
* This cluster pool creates new workers when the others are busy, up to the maximum number of workers.
* When the maximum number of workers is reached and workers are busy, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
* @since 2.0.0
*/
*
* It is possible to perform tasks in sync or asynchronous mode as you prefer.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
* @since 2.0.0
*/
worker.send(message)
}
- /** @inheritDoc */
- protected registerWorkerMessageListener<Message extends Data | Response>(
- worker: Worker,
- listener: (message: MessageValue<Message>) => void
- ): void {
- worker.on('message', listener)
- }
-
/** @inheritDoc */
protected createWorker (): Worker {
return cluster.fork(this.opts.env)
}
- /** @inheritDoc */
- protected afterWorkerSetup (worker: Worker): void {
- // Listen to worker messages.
- this.registerWorkerMessageListener(worker, super.workerListener())
- }
-
/** @inheritDoc */
protected get type (): PoolType {
return PoolTypes.fixed
* Contract definition for a poolifier pool.
*
* @typeParam Worker - Type of worker which manages this pool.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export interface IPool<
Worker extends IWorker,
/**
* Executes the specified function in the worker constructor with the task data input parameter.
*
- * @param data - The task input data for the specified worker function. This can only be serializable data.
+ * @param data - The task input data for the specified worker function. This can only be structured-cloneable data.
* @param name - The name of the worker function to execute. If not specified, the default worker function will be executed.
* @returns Promise that will be fulfilled when the task is completed.
*/
* Worker choice strategy abstract base class.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export abstract class AbstractWorkerChoiceStrategy<
Worker extends IWorker,
* Loosely modeled after the fair queueing algorithm: https://en.wikipedia.org/wiki/Fair_queuing.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class FairShareWorkerChoiceStrategy<
Worker extends IWorker,
* Selects the next worker with an interleaved weighted round robin scheduling algorithm.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class InterleavedWeightedRoundRobinWorkerChoiceStrategy<
Worker extends IWorker,
* Selects the least busy worker.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class LeastBusyWorkerChoiceStrategy<
Worker extends IWorker,
* Selects the worker with the least ELU.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class LeastEluWorkerChoiceStrategy<
Worker extends IWorker,
* Selects the least used worker.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class LeastUsedWorkerChoiceStrategy<
Worker extends IWorker,
* Selects the next worker in a round robin fashion.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class RoundRobinWorkerChoiceStrategy<
Worker extends IWorker,
* Loosely modeled after the weighted round robin queueing algorithm: https://en.wikipedia.org/wiki/Weighted_round_robin.
*
* @typeParam Worker - Type of worker which manages the strategy.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class WeightedRoundRobinWorkerChoiceStrategy<
Worker extends IWorker,
* The worker choice strategy context.
*
* @typeParam Worker - Type of worker.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export class WorkerChoiceStrategyContext<
Worker extends IWorker,
* This thread pool creates new threads when the others are busy, up to the maximum number of threads.
* When the maximum number of threads is reached and workers are busy, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
* @since 0.0.1
*/
import {
- MessageChannel,
SHARE_ENV,
Worker,
type WorkerOptions,
isMainThread
} from 'node:worker_threads'
-import type { Draft, MessageValue } from '../../utility-types'
+import type { MessageValue } from '../../utility-types'
import { AbstractPool } from '../abstract-pool'
import {
type PoolOptions,
workerOptions?: WorkerOptions
}
-/**
- * A thread worker with message channels for communication between main thread and thread worker.
- */
-export type ThreadWorkerWithMessageChannel = Worker & Draft<MessageChannel>
-
/**
* A thread pool with a fixed number of threads.
*
* It is possible to perform tasks in sync or asynchronous mode as you prefer.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
* @since 0.0.1
*/
export class FixedThreadPool<
Data = unknown,
Response = unknown
-> extends AbstractPool<ThreadWorkerWithMessageChannel, Data, Response> {
+> extends AbstractPool<Worker, Data, Response> {
/**
* Constructs a new poolifier fixed thread pool.
*
}
/** @inheritDoc */
- protected async destroyWorker (
- worker: ThreadWorkerWithMessageChannel
- ): Promise<void> {
+ protected async destroyWorker (worker: Worker): Promise<void> {
this.sendToWorker(worker, { kill: 1 })
await worker.terminate()
}
/** @inheritDoc */
- protected sendToWorker (
- worker: ThreadWorkerWithMessageChannel,
- message: MessageValue<Data>
- ): void {
+ protected sendToWorker (worker: Worker, message: MessageValue<Data>): void {
worker.postMessage(message)
}
/** @inheritDoc */
- protected registerWorkerMessageListener<Message extends Data | Response>(
- worker: ThreadWorkerWithMessageChannel,
- listener: (message: MessageValue<Message>) => void
- ): void {
- worker.port2?.on('message', listener)
- }
-
- /** @inheritDoc */
- protected createWorker (): ThreadWorkerWithMessageChannel {
+ protected createWorker (): Worker {
return new Worker(this.filePath, {
env: SHARE_ENV,
...this.opts.workerOptions
})
}
- /** @inheritDoc */
- protected afterWorkerSetup (worker: ThreadWorkerWithMessageChannel): void {
- const { port1, port2 } = new MessageChannel()
- worker.postMessage({ parent: port1 }, [port1])
- worker.port1 = port1
- worker.port2 = port2
- // Listen to worker messages.
- this.registerWorkerMessageListener(worker, super.workerListener())
- }
-
/** @inheritDoc */
protected get type (): PoolType {
return PoolTypes.fixed
*/
export type MessageHandler<Worker extends IWorker> = (
this: Worker,
- m: unknown
+ message: unknown
) => void
/**
*/
export type ErrorHandler<Worker extends IWorker> = (
this: Worker,
- e: Error
+ error: Error
) => void
/**
*/
export type ExitHandler<Worker extends IWorker> = (
this: Worker,
- code: number
+ exitCode: number
) => void
/**
* Message object that is passed as a task between main worker and worker.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
* @internal
*/
export interface Task<Data = unknown> {
* Worker node interface.
*
* @typeParam Worker - Type of worker.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
* @internal
*/
export interface WorkerNode<Worker extends IWorker, Data = unknown> {
* @typeParam T - Type of queue items.
*/
export class Queue<T> {
- private items: T[]
- private offset: number
- public size: number
- public maxSize: number
+ private items!: T[]
+ private offset!: number
+ /** The size of the queue. */
+ public size!: number
+ /** The maximum size of the queue. */
+ public maxSize!: number
public constructor () {
- this.items = []
- this.offset = 0
- /** The size of the queue. */
- this.size = 0
- /** The maximum size of the queue. */
- this.maxSize = 0
+ this.clear()
}
/**
-import type { Worker as ClusterWorker } from 'node:cluster'
-import type { MessagePort } from 'node:worker_threads'
import type { EventLoopUtilization } from 'node:perf_hooks'
import type { KillBehavior } from './worker/worker-options'
import type { IWorker, Task } from './pools/worker'
-/**
- * Make all properties in T non-readonly.
- *
- * @typeParam T - Type in which properties will be non-readonly.
- */
-export type Draft<T> = { -readonly [P in keyof T]?: T[P] }
-
/**
* Task error.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker triggering an error. This can only be structured-cloneable data.
*/
export interface TaskError<Data = unknown> {
/**
/**
* Message object that is passed between main worker and worker.
*
- * @typeParam MessageData - Type of data sent to and/or from the worker. This can only be serializable data.
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker or execution response. This can only be structured-cloneable data.
+ * @typeParam ErrorData - Type of data sent to the worker triggering an error. This can only be structured-cloneable data.
* @typeParam MainWorker - Type of main worker.
* @internal
*/
export interface MessageValue<
- MessageData = unknown,
Data = unknown,
- MainWorker extends ClusterWorker | MessagePort = ClusterWorker | MessagePort
-> extends Task<MessageData> {
+ ErrorData = unknown,
+ MainWorker = NodeJS.Process | MessagePort
+> extends Task<Data> {
/**
* Kill code.
*/
/**
* Task error.
*/
- readonly taskError?: TaskError<Data>
+ readonly taskError?: TaskError<ErrorData>
/**
* Task performance.
*/
* An object holding the execution response promise resolve/reject callbacks.
*
* @typeParam Worker - Type of worker.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
* @internal
*/
export interface PromiseResponseWrapper<
import { AsyncResource } from 'node:async_hooks'
-import type { Worker } from 'node:cluster'
import type { MessagePort } from 'node:worker_threads'
import { performance } from 'node:perf_hooks'
import type {
* Base class that implements some shared logic for all poolifier workers.
*
* @typeParam MainWorker - Type of main worker.
- * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
- * @typeParam Response - Type of response the worker sends back to the main worker. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.
+ * @typeParam Response - Type of response the worker sends back to the main worker. This can only be structured-cloneable data.
*/
export abstract class AbstractWorker<
- MainWorker extends Worker | MessagePort,
+ MainWorker extends NodeJS.Process | MessagePort,
Data = unknown,
Response = unknown
> extends AsyncResource {
taskFunctions:
| WorkerFunction<Data, Response>
| TaskFunctions<Data, Response>,
- protected mainWorker: MainWorker | undefined | null,
+ protected mainWorker: MainWorker,
protected readonly opts: WorkerOptions = {
/**
* The kill behavior option on this worker or its default value.
*/
protected getMainWorker (): MainWorker {
if (this.mainWorker == null) {
- throw new Error('Main worker was not set')
+ throw new Error('Main worker not set')
}
return this.mainWorker
}
-import cluster, { type Worker } from 'node:cluster'
+import cluster from 'node:cluster'
import type { MessageValue } from '../utility-types'
import { AbstractWorker } from './abstract-worker'
import type { WorkerOptions } from './worker-options'
* If you use a `DynamicClusterPool` the extra workers that were created will be terminated,
* but the minimum number of workers will be guaranteed.
*
- * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
- * @typeParam Response - Type of response the worker sends back to the main worker. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.
+ * @typeParam Response - Type of response the worker sends back to the main worker. This can only be structured-cloneable data.
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
* @since 2.0.0
*/
export class ClusterWorker<
Data = unknown,
Response = unknown
-> extends AbstractWorker<Worker, Data, Response> {
+> extends AbstractWorker<NodeJS.Process, Data, Response> {
/**
* Constructs a new poolifier cluster worker.
*
'worker-cluster-pool:poolifier',
cluster.isPrimary,
taskFunctions,
- cluster.worker,
+ process,
opts
)
}
/** @inheritDoc */
protected sendToMainWorker (message: MessageValue<Response>): void {
- this.getMainWorker().send(message)
+ const mainWorker = this.getMainWorker()
+ if (mainWorker.send == null) {
+ throw new Error('Main worker does not support IPC communication')
+ }
+ mainWorker.send(message)
}
/** @inheritDoc */
* If you use a `DynamicThreadPool` the extra workers that were created will be terminated,
* but the minimum number of workers will be guaranteed.
*
- * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
- * @typeParam Response - Type of response the worker sends back to the main thread. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be structured-cloneable data.
+ * @typeParam Response - Type of response the worker sends back to the main thread. This can only be structured-cloneable data.
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
* @since 0.0.1
*/
'worker-thread-pool:poolifier',
isMainThread,
taskFunctions,
- parentPort,
+ parentPort as MessagePort,
opts
)
}
/**
* Worker synchronous function that can be executed.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export type WorkerSyncFunction<Data = unknown, Response = unknown> = (
data?: Data
* Worker asynchronous function that can be executed.
* This function must return a promise.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export type WorkerAsyncFunction<Data = unknown, Response = unknown> = (
data?: Data
* Worker function that can be executed.
* This function can be synchronous or asynchronous.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export type WorkerFunction<Data = unknown, Response = unknown> =
| WorkerSyncFunction<Data, Response>
* The key is the name of the function.
* The value is the function itself.
*
- * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
- * @typeParam Response - Type of execution response. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
+ * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
*/
export type TaskFunctions<Data = unknown, Response = unknown> = Record<
string,
it('Verify that getMainWorker() throw error if main worker is not set', () => {
expect(() =>
new StubWorkerWithMainWorker(() => {}).getMainWorker()
- ).toThrowError('Main worker was not set')
+ ).toThrowError('Main worker not set')
})
})