From: Jérôme Benoit
Date: Mon, 18 Sep 2023 12:12:06 +0000 (+0200)
Subject: Merge dependabot/npm_and_yarn/examples/typescript/http-server-pool/fastify-worker_thr...
X-Git-Tag: v2.7.0~11^2~22
X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=41e3e08eb7fbcde0a69cea17e697aacb222990a6;hp=1dd8d37437003ea05b08f29ddc73a6a6c3849d90;p=poolifier.git
Merge dependabot/npm_and_yarn/examples/typescript/http-server-pool/fastify-worker_threads/types/node-20.6.2 into combined-prs-branch
---
diff --git a/.eslintrc.js b/.eslintrc.js
index 952d603a..97f787ae 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -39,7 +39,6 @@ module.exports = defineConfig({
skipWords: [
'axios',
'benoit',
- 'benny',
'browserslist',
'builtins',
'christopher',
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index b9ed2479..2c346ebc 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -27,7 +27,6 @@ updates:
labels:
- 'dependencies'
- 'benchmarks'
- - 'nocombine'
reviewers:
- 'pioardi'
- 'jerome-benoit'
diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
deleted file mode 100644
index 34655f4c..00000000
--- a/.github/workflows/benchmark.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: Benchmark
-
-on:
- workflow_dispatch:
-
-jobs:
- internal-benchmark:
- strategy:
- matrix:
- os: [windows-latest, macos-latest, ubuntu-latest]
- node: ['16.x', '18.x', '20.x']
-
- name: Internal benchmark with Node.js ${{ matrix.node }} on ${{ matrix.os }}
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: 8
-
- - name: Setup Node.js ${{ matrix.node }}
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node }}
- cache: 'pnpm'
-
- - name: Install
- run: pnpm install --ignore-scripts
-
- - name: Production Benchmark
- run: pnpm benchmark:prod
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5b240db0..3419c571 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -40,7 +40,7 @@ jobs:
node-version: ${{ matrix.node }}
cache: 'pnpm'
- - name: Install
+ - name: Install Dependencies
run: pnpm install --ignore-scripts
- name: Build
diff --git a/.github/workflows/combine-prs.yml b/.github/workflows/combine-prs.yml
index a2c649fe..813a1e3f 100644
--- a/.github/workflows/combine-prs.yml
+++ b/.github/workflows/combine-prs.yml
@@ -1,9 +1,9 @@
name: Combine PRs
on:
- schedule:
- - cron: '0 0 * * *'
workflow_dispatch:
+ schedule:
+ - cron: '0 2 * * *'
permissions:
contents: write
diff --git a/.github/workflows/external-benchmark.yml b/.github/workflows/external-benchmark.yml
new file mode 100644
index 00000000..1f1bf80e
--- /dev/null
+++ b/.github/workflows/external-benchmark.yml
@@ -0,0 +1,48 @@
+name: External benchmark
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '0 3 * * *'
+
+jobs:
+ external-benchmark:
+ if: github.repository == 'poolifier/poolifier'
+ name: External benchmark
+ runs-on: [self-hosted, external-benchmark]
+ defaults:
+ run:
+ working-directory: benchmarks/versus-external-pools
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: 8
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '18.x'
+ cache: 'pnpm'
+ - name: Install dependencies
+ run: pnpm install --ignore-scripts
+ - name: Run benchmark
+ if: github.ref == 'refs/heads/${{ github.event.repository.default_branch }}'
+ run: ./bench.sh
+ - name: Commit files
+ if: github.ref == 'refs/heads/${{ github.event.repository.default_branch }}'
+ env:
+ COMMIT_MESSAGE: 'docs: update benchmark versus external pools results'
+ COMMIT_AUTHOR: Benchmark Bot
+ COMMIT_EMAIL: benchmark-bot@users.noreply.github.com
+ run: |
+ git config --local user.name "${{ env.COMMIT_AUTHOR }}"
+ git config --local user.email "${{ env.COMMIT_EMAIL }}"
+ git commit -a -m "${{ env.COMMIT_MESSAGE }}"
+ - name: Push changes
+ if: github.ref == 'refs/heads/${{ github.event.repository.default_branch }}'
+ uses: CasperWA/push-protected@v2
+ with:
+ token: ${{ secrets.GH_TOKEN_PROTECTED }}
+ branch: ${{ github.event.repository.default_branch }}
diff --git a/.github/workflows/generate-documentation.yml b/.github/workflows/generate-documentation.yml
index fcf24a47..f3d4ae4e 100644
--- a/.github/workflows/generate-documentation.yml
+++ b/.github/workflows/generate-documentation.yml
@@ -29,11 +29,15 @@ jobs:
- name: Commit files
if: github.repository == 'poolifier/poolifier' && github.ref == 'refs/heads/${{ github.event.repository.default_branch }}'
+ env:
+ COMMIT_MESSAGE: 'docs: generate documentation'
+ COMMIT_AUTHOR: Documentation Bot
+ COMMIT_EMAIL: documentation-bot@users.noreply.github.com
run: |
- git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
- git config --local user.name "github-actions[bot]"
+ git config --local user.name "${{ env.COMMIT_AUTHOR }}"
+ git config --local user.email "${{ env.COMMIT_EMAIL }}"
git add ./docs
- git commit -m "docs: generate documentation" -a
+ git commit -a -m "${{ env.COMMIT_MESSAGE }}"
- name: Push changes
if: github.repository == 'poolifier/poolifier' && github.ref == 'refs/heads/${{ github.event.repository.default_branch }}'
diff --git a/.github/workflows/internal-benchmark.yml b/.github/workflows/internal-benchmark.yml
new file mode 100644
index 00000000..46ec1d8f
--- /dev/null
+++ b/.github/workflows/internal-benchmark.yml
@@ -0,0 +1,45 @@
+name: Internal benchmark
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+
+permissions:
+ contents: write
+ deployments: write
+
+jobs:
+ internal-benchmark:
+ if: github.repository == 'poolifier/poolifier'
+ name: Internal benchmark
+ runs-on: [self-hosted, internal-benchmark]
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: 8
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '18.x'
+ cache: 'pnpm'
+ - name: Install dependencies
+ run: pnpm install --ignore-scripts
+ - name: Run production benchmark
+ run: pnpm benchmark:prod | tee ./benchmarks/internal/output.txt
+ - name: Store production benchmark result
+ uses: benchmark-action/github-action-benchmark@v1
+ with:
+ name: Internal benchmark
+ tool: 'benchmarkjs'
+ output-file-path: ./benchmarks/internal/output.txt
+ github-token: ${{ secrets.BENCHMARK_RESULTS_TOKEN }}
+ auto-push: true
+ alert-threshold: '200%'
+ comment-on-alert: true
+ fail-on-alert: true
+ gh-repository: 'github.com/poolifier/benchmark-results'
diff --git a/.github/workflows/npmpublish.yml b/.github/workflows/publish-package.yml
similarity index 96%
rename from .github/workflows/npmpublish.yml
rename to .github/workflows/publish-package.yml
index 751e936b..ef3fc5fe 100644
--- a/.github/workflows/npmpublish.yml
+++ b/.github/workflows/publish-package.yml
@@ -1,4 +1,4 @@
-name: Node.js Package
+name: Publish package
on:
release:
@@ -23,7 +23,7 @@ jobs:
node-version: '18.x'
cache: 'pnpm'
- - name: Install
+ - name: Install Dependencies
run: pnpm install --ignore-scripts
- name: Tests & Coverage
@@ -57,7 +57,7 @@ jobs:
registry-url: https://registry.npmjs.org/
cache: 'pnpm'
- - name: Install
+ - name: Install Dependencies
run: pnpm install --ignore-scripts
- name: Read package.json version
@@ -105,7 +105,7 @@ jobs:
# registry-url: https://npm.pkg.github.com
# cache: 'pnpm'
- # - name: Install
+ # - name: Install Dependencies
# run: pnpm install --ignore-scripts
# - name: Read package.json version
diff --git a/.gitignore b/.gitignore
index 404473ff..5e16da97 100644
--- a/.gitignore
+++ b/.gitignore
@@ -79,4 +79,3 @@ lib
dist
tmp
reports/
-benchmarks/internal/results/
diff --git a/.vscode/settings.json b/.vscode/settings.json
index a3b7be46..22ada289 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -32,7 +32,6 @@
"mochawesome",
"MYBENCH",
"nanothreads",
- "nocombine",
"nproc",
"octocat",
"opencollective",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 59182946..ad5bfde0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,10 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+### Fixed
+
+- Fix task stealing related tasks queue options handling at runtime.
+
+### Changed
+
+- Stricter worker constructor arguments validation.
+
+## [2.6.45] - 2023-09-17
+
### Changed
- Disable publication on GitHub packages registry on release until authentication issue is fixed.
+### Added
+
+- Add `startWorkers` to pool options to whether start the minimum number of workers at pool creation or not.
+- Add `start()` method to pool API to start the minimum number of workers.
+- Add `taskStealing` and `tasksStealingOnPressure` to tasks queue options to whether enable task stealing or not and whether enable tasks stealing on back pressure or not.
+- Continuous internal benchmarking: https://poolifier.github.io/benchmark-results/dev/bench.
+
## [2.6.44] - 2023-09-08
### Fixed
@@ -645,7 +662,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Optimize worker alive status check.
- BREAKING CHANGE: Rename worker choice strategy `LESS_RECENTLY_USED` to `LESS_USED`.
- Optimize `LESS_USED` worker choice strategy.
-- Update benchmarks versus external threads pools.
+- Update benchmark versus external threads pools.
- Optimize tasks usage statistics requirements for worker choice strategy.
### Fixed
@@ -667,7 +684,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Optimize worker alive status check.
- BREAKING CHANGE: Rename worker choice strategy `LESS_RECENTLY_USED` to `LESS_USED`.
- Optimize `LESS_USED` worker choice strategy.
-- Update benchmarks versus external threads pools.
+- Update benchmark versus external threads pools.
### Fixed
@@ -833,7 +850,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Optimize fair share task scheduling algorithm implementation.
-- Update benchmarks versus external pools results with latest version.
+- Update benchmark versus external pools results with latest version.
## [2.3.3] - 2022-10-15
diff --git a/benchmarks/README.md b/benchmarks/README.md
index b2ee4336..33b81f4e 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -4,8 +4,8 @@ Welcome to poolifier benchmarks and thanks to look into this project.
## Folder Structure
-The [internal](./internal) folder contains poolifier internal benchmarks.
-The [versus-external-pools](./versus-external-pools) folder contains benchmarks versus other Node.js pools.
+The [internal](./internal) folder contains poolifier internal benchmark.
+The [versus-external-pools](./versus-external-pools) folder contains benchmark versus other Node.js pools.
## Poolifier vs other pools benchmark
@@ -34,10 +34,14 @@ We chose to use this tool because it allows to run isolated Node.js processes so
- [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.
-> :warning: **We would need funds to run our benchmarks more often and on Cloud VMs, please consider to sponsor this project**
+> :warning: **We would need funds to run our benchmark more often and on Cloud VMs, please consider to sponsor this project**
-Read the [README.md](./versus-external-pools/README.md) to know how to run these benchmarks.
+Read the [README.md](./versus-external-pools/README.md) to know how to run the benchmark.
## Poolifier internal benchmark
-To run the internal benchmarks, you just need to navigate to the root of poolifier project and run `pnpm benchmark`
+### Usage
+
+To run the internal benchmark, you just need to navigate to the root of poolifier project and run `pnpm benchmark`.
+
+### [Results](https://poolifier.github.io/benchmark-results/dev/bench)
diff --git a/benchmarks/benchmarks-utils.mjs b/benchmarks/benchmarks-utils.mjs
index 0aeca085..79971825 100644
--- a/benchmarks/benchmarks-utils.mjs
+++ b/benchmarks/benchmarks-utils.mjs
@@ -1,11 +1,15 @@
import crypto from 'node:crypto'
+import assert from 'node:assert'
import fs from 'node:fs'
+import Benchmark from 'benchmark'
import {
DynamicClusterPool,
DynamicThreadPool,
FixedClusterPool,
FixedThreadPool,
+ Measurements,
PoolTypes,
+ WorkerChoiceStrategies,
WorkerTypes
} from '../lib/index.mjs'
import { TaskFunctions } from './benchmarks-types.mjs'
@@ -54,11 +58,11 @@ export const buildPoolifierPool = (
}
}
-export const runPoolifierTest = async (
+export const runPoolifierPool = async (
pool,
{ taskExecutions, workerData }
) => {
- return new Promise((resolve, reject) => {
+ return await new Promise((resolve, reject) => {
let executions = 0
for (let i = 1; i <= taskExecutions; i++) {
pool
@@ -66,28 +70,109 @@ export const runPoolifierTest = async (
.then(() => {
++executions
if (executions === taskExecutions) {
- return resolve({ ok: 1 })
+ resolve({ ok: 1 })
}
return null
})
.catch(err => {
console.error(err)
- return reject(err)
+ reject(err)
})
}
})
}
-export const executeAsyncFn = async fn => {
- try {
- await fn()
- } catch (e) {
- console.error(e)
- // eslint-disable-next-line n/no-process-exit
- process.exit(1)
- }
+export const runPoolifierPoolBenchmark = async (
+ name,
+ pool,
+ { taskExecutions, workerData }
+) => {
+ return await new Promise((resolve, reject) => {
+ try {
+ const suite = new Benchmark.Suite(name)
+ for (const workerChoiceStrategy of Object.values(
+ WorkerChoiceStrategies
+ )) {
+ for (const enableTasksQueue of [false, true]) {
+ if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
+ for (const measurement of [
+ Measurements.runTime,
+ Measurements.elu
+ ]) {
+ suite.add(
+ `${name} with ${workerChoiceStrategy}, with ${measurement} and ${
+ enableTasksQueue ? 'with' : 'without'
+ } tasks queue`,
+ async () => {
+ pool.setWorkerChoiceStrategy(workerChoiceStrategy, {
+ measurement
+ })
+ pool.enableTasksQueue(enableTasksQueue)
+ assert.strictEqual(
+ pool.opts.workerChoiceStrategy,
+ workerChoiceStrategy
+ )
+ assert.strictEqual(
+ pool.opts.enableTasksQueue,
+ enableTasksQueue
+ )
+ assert.strictEqual(
+ pool.opts.workerChoiceStrategyOptions.measurement,
+ measurement
+ )
+ await runPoolifierPool(pool, {
+ taskExecutions,
+ workerData
+ })
+ }
+ )
+ }
+ } else {
+ suite.add(
+ `${name} with ${workerChoiceStrategy} and ${
+ enableTasksQueue ? 'with' : 'without'
+ } tasks queue`,
+ async () => {
+ pool.setWorkerChoiceStrategy(workerChoiceStrategy)
+ pool.enableTasksQueue(enableTasksQueue)
+ assert.strictEqual(
+ pool.opts.workerChoiceStrategy,
+ workerChoiceStrategy
+ )
+ assert.strictEqual(pool.opts.enableTasksQueue, enableTasksQueue)
+ await runPoolifierPool(pool, {
+ taskExecutions,
+ workerData
+ })
+ }
+ )
+ }
+ }
+ }
+ suite
+ .on('cycle', event => {
+ console.info(event.target.toString())
+ })
+ .on('complete', async function () {
+ console.info(
+ 'Fastest is ' +
+ LIST_FORMATTER.format(this.filter('fastest').map('name'))
+ )
+ await pool.destroy()
+ resolve()
+ })
+ .run({ async: true })
+ } catch (error) {
+ reject(error)
+ }
+ })
}
+export const LIST_FORMATTER = new Intl.ListFormat('en-US', {
+ style: 'long',
+ type: 'conjunction'
+})
+
export const generateRandomInteger = (
max = Number.MAX_SAFE_INTEGER,
min = 0
diff --git a/benchmarks/internal/bench.mjs b/benchmarks/internal/bench.mjs
index a14ecd5f..3484951c 100644
--- a/benchmarks/internal/bench.mjs
+++ b/benchmarks/internal/bench.mjs
@@ -1,93 +1,37 @@
-import { add, complete, cycle, save, suite } from 'benny'
import {
- Measurements,
PoolTypes,
- WorkerChoiceStrategies,
WorkerTypes,
availableParallelism
} from '../../lib/index.mjs'
import { TaskFunctions } from '../benchmarks-types.mjs'
-import { buildPoolifierPool, runPoolifierTest } from '../benchmarks-utils.mjs'
+import {
+ buildPoolifierPool,
+ runPoolifierPoolBenchmark
+} from '../benchmarks-utils.mjs'
const poolSize = availableParallelism()
-const pools = []
-for (const poolType of Object.values(PoolTypes)) {
- for (const workerType of Object.values(WorkerTypes)) {
- if (workerType === WorkerTypes.cluster) {
- continue
- }
- for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
- for (const enableTasksQueue of [false, true]) {
- if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
- for (const measurement of [Measurements.runTime, Measurements.elu]) {
- pools.push([
- `${poolType}|${workerType}|${workerChoiceStrategy}|tasks queue:${enableTasksQueue}|measurement:${measurement}`,
- buildPoolifierPool(workerType, poolType, poolSize, {
- workerChoiceStrategy,
- workerChoiceStrategyOptions: {
- measurement
- },
- enableTasksQueue
- })
- ])
- }
- } else {
- pools.push([
- `${poolType}|${workerType}|${workerChoiceStrategy}|tasks queue:${enableTasksQueue}`,
- buildPoolifierPool(workerType, poolType, poolSize, {
- workerChoiceStrategy,
- enableTasksQueue
- })
- ])
- }
- }
- }
- }
-}
-
const taskExecutions = 1
const workerData = {
function: TaskFunctions.jsonIntegerSerialization,
taskSize: 1000
}
-const addPools = pools =>
- pools.map(([name, pool]) => {
- return add(name, async () => {
- await runPoolifierTest(pool, {
- taskExecutions,
- workerData
- })
- })
- })
-const resultsFile = 'poolifier'
-const resultsFolder = 'benchmarks/internal/results'
-suite(
- 'Poolifier',
- ...addPools(pools),
- cycle(),
- complete(),
- save({
- file: resultsFile,
- folder: resultsFolder,
- format: 'json',
- details: true
- }),
- save({
- file: resultsFile,
- folder: resultsFolder,
- format: 'chart.html',
- details: true
- }),
- save({
- file: resultsFile,
- folder: resultsFolder,
- format: 'table.html',
- details: true
- })
+// FixedThreadPool
+await runPoolifierPoolBenchmark(
+ 'Poolifier FixedThreadPool',
+ buildPoolifierPool(WorkerTypes.thread, PoolTypes.fixed, poolSize),
+ {
+ taskExecutions,
+ workerData
+ }
+)
+
+// DynamicThreadPool
+await runPoolifierPoolBenchmark(
+ 'Poolifier DynamicThreadPool',
+ buildPoolifierPool(WorkerTypes.thread, PoolTypes.dynamic, poolSize),
+ {
+ taskExecutions,
+ workerData
+ }
)
- .then(() => {
- // eslint-disable-next-line n/no-process-exit
- return process.exit()
- })
- .catch(err => console.error(err))
diff --git a/benchmarks/internal/cluster-worker.mjs b/benchmarks/internal/cluster-worker.mjs
index 69a7ad15..1d64fde3 100644
--- a/benchmarks/internal/cluster-worker.mjs
+++ b/benchmarks/internal/cluster-worker.mjs
@@ -3,13 +3,12 @@ import { ClusterWorker } from '../../lib/index.mjs'
import { executeTaskFunction } from '../benchmarks-utils.mjs'
import { TaskFunctions } from '../benchmarks-types.mjs'
-const debug = false
-
const taskFunction = data => {
data = data || {}
data.function = data.function || TaskFunctions.jsonIntegerSerialization
+ data.debug = data.debug || false
const res = executeTaskFunction(data)
- debug === true && console.debug(`This is the main thread ${isPrimary}`)
+ data.debug === true && console.debug(`This is the main thread ${isPrimary}`)
return res
}
diff --git a/benchmarks/internal/thread-worker.mjs b/benchmarks/internal/thread-worker.mjs
index 7af5fa63..5c6a691e 100644
--- a/benchmarks/internal/thread-worker.mjs
+++ b/benchmarks/internal/thread-worker.mjs
@@ -3,13 +3,13 @@ import { ThreadWorker } from '../../lib/index.mjs'
import { executeTaskFunction } from '../benchmarks-utils.mjs'
import { TaskFunctions } from '../benchmarks-types.mjs'
-const debug = false
-
const taskFunction = data => {
data = data || {}
data.function = data.function || TaskFunctions.jsonIntegerSerialization
+ data.debug = data.debug || false
const res = executeTaskFunction(data)
- debug === true && console.debug(`This is the main thread ${isMainThread}`)
+ data.debug === true &&
+ console.debug(`This is the main thread ${isMainThread}`)
return res
}
diff --git a/benchmarks/versus-external-pools/bench.sh b/benchmarks/versus-external-pools/bench.sh
index 7221ba32..7d7e9651 100755
--- a/benchmarks/versus-external-pools/bench.sh
+++ b/benchmarks/versus-external-pools/bench.sh
@@ -51,7 +51,7 @@ case "$OSTYPE" in
caffeinate ./hyperfine_benchmarks.sh
;;
linux*)
- systemd-inhibit ./hyperfine_benchmarks.sh
+ systemd-inhibit --what=idle ./hyperfine_benchmarks.sh
;;
*)
echo "Unsupported $OSTYPE"
diff --git a/benchmarks/versus-external-pools/dynamic-node-worker-threads-pool.mjs b/benchmarks/versus-external-pools/dynamic-node-worker-threads-pool.mjs
index 08535b68..c4be1ee1 100644
--- a/benchmarks/versus-external-pools/dynamic-node-worker-threads-pool.mjs
+++ b/benchmarks/versus-external-pools/dynamic-node-worker-threads-pool.mjs
@@ -1,5 +1,5 @@
import { DynamicPool } from 'node-worker-threads-pool'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
import functionToBench from './functions/function-to-bench.js'
const size = parseInt(process.env.POOL_SIZE)
diff --git a/benchmarks/versus-external-pools/dynamic-piscina.mjs b/benchmarks/versus-external-pools/dynamic-piscina.mjs
index 3f56a699..06c71779 100644
--- a/benchmarks/versus-external-pools/dynamic-piscina.mjs
+++ b/benchmarks/versus-external-pools/dynamic-piscina.mjs
@@ -1,5 +1,5 @@
import Piscina from 'piscina'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/dynamic-poolifier.mjs b/benchmarks/versus-external-pools/dynamic-poolifier.mjs
index 33ac343c..98d21006 100644
--- a/benchmarks/versus-external-pools/dynamic-poolifier.mjs
+++ b/benchmarks/versus-external-pools/dynamic-poolifier.mjs
@@ -1,5 +1,5 @@
import { DynamicThreadPool } from 'poolifier'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/dynamic-tinypool.mjs b/benchmarks/versus-external-pools/dynamic-tinypool.mjs
index 77b5d111..3c00b134 100644
--- a/benchmarks/versus-external-pools/dynamic-tinypool.mjs
+++ b/benchmarks/versus-external-pools/dynamic-tinypool.mjs
@@ -1,5 +1,5 @@
import Tinypool from 'tinypool'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/dynamic-workerpool.mjs b/benchmarks/versus-external-pools/dynamic-workerpool.mjs
index 0e09f1bb..f3baa446 100644
--- a/benchmarks/versus-external-pools/dynamic-workerpool.mjs
+++ b/benchmarks/versus-external-pools/dynamic-workerpool.mjs
@@ -1,5 +1,5 @@
import workerpool from 'workerpool'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/fixed-nanothreads.mjs b/benchmarks/versus-external-pools/fixed-nanothreads.mjs
index d5572059..d18f71b5 100644
--- a/benchmarks/versus-external-pools/fixed-nanothreads.mjs
+++ b/benchmarks/versus-external-pools/fixed-nanothreads.mjs
@@ -1,5 +1,5 @@
import { ThreadPool } from 'nanothreads'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
import functionToBench from './functions/function-to-bench.js'
const size = parseInt(process.env.POOL_SIZE)
diff --git a/benchmarks/versus-external-pools/fixed-piscina.mjs b/benchmarks/versus-external-pools/fixed-piscina.mjs
index 97150f5e..761586ac 100644
--- a/benchmarks/versus-external-pools/fixed-piscina.mjs
+++ b/benchmarks/versus-external-pools/fixed-piscina.mjs
@@ -1,5 +1,5 @@
import Piscina from 'piscina'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/fixed-poolifier.mjs b/benchmarks/versus-external-pools/fixed-poolifier.mjs
index 7cfd651d..5efd786e 100644
--- a/benchmarks/versus-external-pools/fixed-poolifier.mjs
+++ b/benchmarks/versus-external-pools/fixed-poolifier.mjs
@@ -1,5 +1,5 @@
import { FixedThreadPool } from 'poolifier'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/fixed-tinypool.mjs b/benchmarks/versus-external-pools/fixed-tinypool.mjs
index 7063b5b9..307ac3b5 100644
--- a/benchmarks/versus-external-pools/fixed-tinypool.mjs
+++ b/benchmarks/versus-external-pools/fixed-tinypool.mjs
@@ -1,5 +1,5 @@
import Tinypool from 'tinypool'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/fixed-workerpool.mjs b/benchmarks/versus-external-pools/fixed-workerpool.mjs
index 6387b84e..9e016331 100644
--- a/benchmarks/versus-external-pools/fixed-workerpool.mjs
+++ b/benchmarks/versus-external-pools/fixed-workerpool.mjs
@@ -1,5 +1,5 @@
import workerpool from 'workerpool'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
const size = parseInt(process.env.POOL_SIZE)
const iterations = parseInt(process.env.NUM_ITERATIONS)
diff --git a/benchmarks/versus-external-pools/package.json b/benchmarks/versus-external-pools/package.json
index 6b06dc7d..3ba2d034 100644
--- a/benchmarks/versus-external-pools/package.json
+++ b/benchmarks/versus-external-pools/package.json
@@ -12,7 +12,7 @@
},
"volta": {
"node": "18.17.1",
- "pnpm": "8.7.5"
+ "pnpm": "8.7.6"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
diff --git a/benchmarks/versus-external-pools/static-node-worker-threads-pool.mjs b/benchmarks/versus-external-pools/static-node-worker-threads-pool.mjs
index d37677cd..db14b180 100644
--- a/benchmarks/versus-external-pools/static-node-worker-threads-pool.mjs
+++ b/benchmarks/versus-external-pools/static-node-worker-threads-pool.mjs
@@ -1,5 +1,5 @@
import { StaticPool } from 'node-worker-threads-pool'
-import { executeAsyncFn } from '../benchmarks-utils.mjs'
+import { executeAsyncFn } from './utils.mjs'
import functionToBench from './functions/function-to-bench.js'
const size = parseInt(process.env.POOL_SIZE)
diff --git a/benchmarks/versus-external-pools/utils.mjs b/benchmarks/versus-external-pools/utils.mjs
new file mode 100644
index 00000000..3d26ea16
--- /dev/null
+++ b/benchmarks/versus-external-pools/utils.mjs
@@ -0,0 +1,9 @@
+export const executeAsyncFn = async fn => {
+ try {
+ await fn()
+ } catch (e) {
+ console.error(e)
+ // eslint-disable-next-line n/no-process-exit
+ process.exit(1)
+ }
+}
diff --git a/benchmarks/worker-selection/less.mjs b/benchmarks/worker-selection/least.mjs
similarity index 85%
rename from benchmarks/worker-selection/less.mjs
rename to benchmarks/worker-selection/least.mjs
index e839107d..2abbae82 100644
--- a/benchmarks/worker-selection/less.mjs
+++ b/benchmarks/worker-selection/least.mjs
@@ -1,5 +1,5 @@
-import Benchmark from 'benny'
-import { generateRandomInteger } from '../benchmarks-utils.mjs'
+import Benchmark from 'benchmark'
+import { LIST_FORMATTER, generateRandomInteger } from '../benchmarks-utils.mjs'
function generateRandomTasksMap (
numberOfWorkers,
@@ -16,8 +16,8 @@ function generateRandomTasksMap (
const tasksMap = generateRandomTasksMap(60, 20)
function loopSelect (tasksMap) {
- let minValue = Infinity
let minKey
+ let minValue = Infinity
for (const [key, value] of tasksMap) {
if (value === 0) {
return key
@@ -167,26 +167,31 @@ function quickSelectRecursionRandomPivot (tasksMap) {
)
}
-Benchmark.suite(
- 'Least used worker tasks distribution',
- Benchmark.add('Loop select', () => {
+new Benchmark.Suite('Least used worker tasks distribution')
+ .add('Loop select', () => {
loopSelect(tasksMap)
- }),
- Benchmark.add('Array sort select', () => {
+ })
+ .add('Array sort select', () => {
arraySortSelect(tasksMap)
- }),
- Benchmark.add('Quick select loop', () => {
+ })
+ .add('Quick select loop', () => {
quickSelectLoop(tasksMap)
- }),
- Benchmark.add('Quick select loop with random pivot', () => {
+ })
+ .add('Quick select loop with random pivot', () => {
quickSelectLoopRandomPivot(tasksMap)
- }),
- Benchmark.add('Quick select recursion', () => {
+ })
+ .add('Quick select recursion', () => {
quickSelectRecursion(tasksMap)
- }),
- Benchmark.add('Quick select recursion with random pivot', () => {
+ })
+ .add('Quick select recursion with random pivot', () => {
quickSelectRecursionRandomPivot(tasksMap)
- }),
- Benchmark.cycle(),
- Benchmark.complete()
-)
+ })
+ .on('cycle', event => {
+ console.info(event.target.toString())
+ })
+ .on('complete', function () {
+ console.info(
+ 'Fastest is ' + LIST_FORMATTER.format(this.filter('fastest').map('name'))
+ )
+ })
+ .run()
diff --git a/benchmarks/worker-selection/round-robin.mjs b/benchmarks/worker-selection/round-robin.mjs
index b724a04a..483098d2 100644
--- a/benchmarks/worker-selection/round-robin.mjs
+++ b/benchmarks/worker-selection/round-robin.mjs
@@ -1,4 +1,5 @@
-import Benchmark from 'benny'
+import Benchmark from 'benchmark'
+import { LIST_FORMATTER } from '../benchmarks-utils.mjs'
function generateWorkersArray (numberOfWorkers) {
return [...Array(numberOfWorkers).keys()]
@@ -36,24 +37,29 @@ function roundRobinIncrementModulo () {
return chosenWorker
}
-Benchmark.suite(
- 'Round robin tasks distribution',
- Benchmark.add('Ternary off by one', () => {
+new Benchmark.Suite('Round robin tasks distribution')
+ .add('Ternary off by one', () => {
nextWorkerIndex = 0
roundRobinTernaryOffByOne()
- }),
- Benchmark.add('Ternary with negation', () => {
+ })
+ .add('Ternary with negation', () => {
nextWorkerIndex = 0
roundRobinTernaryWithNegation()
- }),
- Benchmark.add('Ternary with pre-choosing', () => {
+ })
+ .add('Ternary with pre-choosing', () => {
nextWorkerIndex = 0
roundRobinTernaryWithPreChoosing()
- }),
- Benchmark.add('Increment+Modulo', () => {
+ })
+ .add('Increment+Modulo', () => {
nextWorkerIndex = 0
roundRobinIncrementModulo()
- }),
- Benchmark.cycle(),
- Benchmark.complete()
-)
+ })
+ .on('cycle', event => {
+ console.info(event.target.toString())
+ })
+ .on('complete', function () {
+ console.info(
+ 'Fastest is ' + LIST_FORMATTER.format(this.filter('fastest').map('name'))
+ )
+ })
+ .run()
diff --git a/biome.json b/biome.json
index 56ea3618..54a21abe 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/1.2.1/schema.json",
+ "$schema": "https://biomejs.dev/schemas/1.2.2/schema.json",
"organizeImports": {
"enabled": false
},
@@ -30,7 +30,6 @@
"files": {
"ignore": [
".nyc_output/",
- ".vscode/",
"benchmarks/internal/results/",
"coverage/",
"docs/**/*.css",
diff --git a/docs/api.md b/docs/api.md
index 07133926..df7d1ce5 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -6,6 +6,7 @@
- [`pool = new FixedThreadPool/FixedClusterPool(numberOfThreads/numberOfWorkers, filePath, opts)`](#pool--new-fixedthreadpoolfixedclusterpoolnumberofthreadsnumberofworkers-filepath-opts)
- [`pool = new DynamicThreadPool/DynamicClusterPool(min, max, filePath, opts)`](#pool--new-dynamicthreadpooldynamicclusterpoolmin-max-filepath-opts)
- [`pool.execute(data, name, transferList)`](#poolexecutedata-name-transferlist)
+ - [`pool.start()`](#poolstart)
- [`pool.destroy()`](#pooldestroy)
- [`pool.listTaskFunctions()`](#poollisttaskfunctions)
- [`PoolOptions`](#pooloptions)
@@ -23,25 +24,29 @@
### `pool = new FixedThreadPool/FixedClusterPool(numberOfThreads/numberOfWorkers, filePath, opts)`
-`numberOfThreads/numberOfWorkers` (mandatory) Number of workers for this pool
-`filePath` (mandatory) Path to a file with a worker implementation
-`opts` (optional) An object with the pool options properties described below
+`numberOfThreads/numberOfWorkers` (mandatory) Number of workers for this pool.
+`filePath` (mandatory) Path to a file with a worker implementation.
+`opts` (optional) An object with the pool options properties described below.
### `pool = new DynamicThreadPool/DynamicClusterPool(min, max, filePath, opts)`
-`min` (mandatory) Same as _FixedThreadPool_/_FixedClusterPool_ numberOfThreads/numberOfWorkers, this number of workers will be always active
+`min` (mandatory) Same as _FixedThreadPool_/_FixedClusterPool_ numberOfThreads/numberOfWorkers, this number of workers will be always active.
`max` (mandatory) Max number of workers that this pool can contain, the newly created workers will die after a threshold (default is 1 minute, you can override it in your worker implementation).
-`filePath` (mandatory) Path to a file with a worker implementation
-`opts` (optional) An object with the pool options properties described below
+`filePath` (mandatory) Path to a file with a worker implementation.
+`opts` (optional) An object with the pool options properties described below.
### `pool.execute(data, name, transferList)`
-`data` (optional) An object that you want to pass to your worker implementation
+`data` (optional) An object that you want to pass to your worker implementation.
`name` (optional) A string with the task function name that you want to execute on the worker. Default: `'default'`
`transferList` (optional) An array of transferable objects that you want to transfer to your [worker_threads](https://nodejs.org/api/worker_threads.html) worker implementation
This method is available on both pool implementations and returns a promise with the task function execution response.
+### `pool.start()`
+
+This method is available on both pool implementations and will start the minimum number of workers.
+
### `pool.destroy()`
This method is available on both pool implementations and will call the terminate method on each worker.
@@ -54,10 +59,15 @@ This method is available on both pool implementations and returns an array of th
An object with these properties:
-- `onlineHandler` (optional) - A function that will listen for online event on each worker
-- `messageHandler` (optional) - A function that will listen for message event on each worker
-- `errorHandler` (optional) - A function that will listen for error event on each worker
-- `exitHandler` (optional) - A function that will listen for exit event on each worker
+- `onlineHandler` (optional) - A function that will listen for online event on each worker.
+ Default: `() => {}`
+- `messageHandler` (optional) - A function that will listen for message event on each worker.
+ Default: `() => {}`
+- `errorHandler` (optional) - A function that will listen for error event on each worker.
+ Default: `() => {}`
+- `exitHandler` (optional) - A function that will listen for exit event on each worker.
+ Default: `() => {}`
+
- `workerChoiceStrategy` (optional) - The worker choice strategy to use in this pool:
- `WorkerChoiceStrategies.ROUND_ROBIN`: Submit tasks to worker in a round robin fashion
@@ -83,6 +93,8 @@ An object with these properties:
Default: `{ retries: 6, runTime: { median: false }, waitTime: { median: false }, elu: { median: false } }`
+- `startWorkers` (optional) - Start the minimum number of workers at pool creation.
+ Default: `true`
- `restartWorkerOnError` (optional) - Restart worker on uncaught error in this pool.
Default: `true`
- `enableEvents` (optional) - Events emission enablement in this pool.
@@ -95,8 +107,10 @@ An object with these properties:
- `size` (optional) - The maximum number of tasks that can be queued on a worker before flagging it as back pressured. It must be a positive integer.
- `concurrency` (optional) - The maximum number of tasks that can be executed concurrently on a worker. It must be a positive integer.
+ - `taskStealing` (optional) - Task stealing enablement.
+ - `tasksStealingOnBackPressure` (optional) - Tasks stealing enablement on back pressure.
- Default: `{ size: (pool maximum size)^2, concurrency: 1 }`
+ Default: `{ size: (pool maximum size)^2, concurrency: 1, taskStealing: true, tasksStealingOnBackPressure: true }`
#### `ThreadPoolOptions extends PoolOptions`
@@ -112,7 +126,7 @@ An object with these properties:
### `class YourWorker extends ThreadWorker/ClusterWorker`
-`taskFunctions` (mandatory) The task function or task functions object `{ name_1: fn_1, ..., name_n: fn_n }` that you want to execute on the worker
+`taskFunctions` (mandatory) The task function or task functions object `{ name_1: fn_1, ..., name_n: fn_n }` that you want to execute on the worker.
`opts` (optional) An object with these properties:
- `killBehavior` (optional) - Dictates if your worker will be deleted in case a task is active on it.
@@ -121,7 +135,7 @@ An object with these properties:
This option only apply to the newly created workers.
Default: `KillBehaviors.SOFT`
-- `maxInactiveTime` (optional) - Maximum waiting time in milliseconds for tasks on newly created workers. After this time newly created workers will die.
+- `maxInactiveTime` (optional) - Maximum waiting time in milliseconds for tasks on newly created workers. After this time newly created workers will die. It must be a positive integer greater or equal than 5.
The last active time of your worker will be updated when it terminates a task.
If `killBehavior` is set to `KillBehaviors.HARD` this value represents also the timeout for the tasks that you submit to the pool, when this timeout expires your tasks is interrupted before completion and removed. The worker is killed if is not part of the minimum size of the pool.
If `killBehavior` is set to `KillBehaviors.SOFT` your tasks have no timeout and your workers will not be terminated until your task is completed.
@@ -132,20 +146,20 @@ An object with these properties:
#### `YourWorker.hasTaskFunction(name)`
-`name` (mandatory) The task function name
+`name` (mandatory) The task function name.
This method is available on both worker implementations and returns a boolean.
#### `YourWorker.addTaskFunction(name, fn)`
-`name` (mandatory) The task function name
-`fn` (mandatory) The task function
+`name` (mandatory) The task function name.
+`fn` (mandatory) The task function.
This method is available on both worker implementations and returns a boolean.
#### `YourWorker.removeTaskFunction(name)`
-`name` (mandatory) The task function name
+`name` (mandatory) The task function name.
This method is available on both worker implementations and returns a boolean.
@@ -155,6 +169,6 @@ This method is available on both worker implementations and returns an array of
#### `YourWorker.setDefaultTaskFunction(name)`
-`name` (mandatory) The task function name
+`name` (mandatory) The task function name.
This method is available on both worker implementations and returns a boolean.
diff --git a/docs/assets/search.js b/docs/assets/search.js
index 196ebf01..a3787771 100644
--- a/docs/assets/search.js
+++ b/docs/assets/search.js
@@ -1 +1 @@
-window.searchData = "data:application/octet-stream;base64,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";
\ No newline at end of file
+window.searchData = "data:application/octet-stream;base64,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";
\ No newline at end of file
diff --git a/docs/classes/AbstractPool.html b/docs/classes/AbstractPool.html
index e306ebe9..19f0f6a1 100644
--- a/docs/classes/AbstractPool.html
+++ b/docs/classes/AbstractPool.html
@@ -1,4 +1,4 @@
-AbstractPool | poolifier - v2.6.44
+AbstractPool | poolifier - v2.6.45
@@ -49,7 +49,7 @@
- IPool<Worker, Data, Response>
+
Defined in src/pools/abstract-pool.ts:59
+
Defined in src/pools/abstract-pool.ts:114
Protected
Readonly
filePath
filePath: string
@@ -220,7 +224,7 @@
+
Defined in src/pools/abstract-pool.ts:116
Protected
Optional
Readonly
max
max?: number
@@ -228,7 +232,7 @@
+Defined in src/pools/abstract-pool.ts:92
Protected
Readonly
numberOfWorkers
numberOfWorkers: number
@@ -236,7 +240,7 @@
+Defined in src/pools/abstract-pool.ts:115
Protected
Readonly
opts
@@ -244,11 +248,11 @@
+Defined in src/pools/abstract-pool.ts:117
Protected
promiseResponseMap
-
+Defined in src/pools/abstract-pool.ts:105
Private
started
started: boolean
@@ -273,15 +277,15 @@
+Defined in src/pools/abstract-pool.ts:97
-Private
Readonly
starting
+Private
starting
starting: boolean
+Defined in src/pools/abstract-pool.ts:101
Protected
workerChoiceStrategyContext
@@ -289,7 +293,7 @@
+Defined in src/pools/abstract-pool.ts:83
Readonly
Internal
workerNodes
@@ -298,7 +302,7 @@
+Defined in src/pools/abstract-pool.ts:65
Protected
full
@@ -324,7 +328,7 @@
Returns boolean
+Defined in src/pools/abstract-pool.ts:722
+Defined in src/pools/abstract-pool.ts:342
Protected
maxSize
@@ -347,7 +351,7 @@
Returns number
+Defined in src/pools/abstract-pool.ts:555
Protected
minSize
@@ -358,7 +362,7 @@
Returns number
+Defined in src/pools/abstract-pool.ts:548
Private
ready
@@ -369,7 +373,7 @@
Returns boolean
+Defined in src/pools/abstract-pool.ts:500
Protected
Abstract
type
@@ -381,7 +385,7 @@
Returns "fixed" | "dynamic"
+Defined in src/pools/abstract-pool.ts:538
+Defined in src/pools/abstract-pool.ts:517
Protected
Abstract
worker
@@ -404,7 +408,7 @@
Returns "thread" | "cluster"
+Defined in src/pools/abstract-pool.ts:543
Protected
afterTaskExecutionHook
@@ -453,7 +457,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:935
Protected
afterWorkerNodeSetup
@@ -473,7 +477,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:1209
Protected
beforeTaskExecutionHook
@@ -498,7 +502,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:905
Private
buildTasksQueueOptions
@@ -511,7 +515,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:671
Private
checkAndEmitDynamicWorkerCreationEvents
@@ -519,7 +523,7 @@ Can be overridden.
-
Returns void
+Defined in src/pools/abstract-pool.ts:1444
Private
checkAndEmitTaskExecutionEvents
@@ -527,7 +531,7 @@ Can be overridden.
-
Returns void
+Defined in src/pools/abstract-pool.ts:1432
Private
checkAndEmitTaskQueuingEvents
@@ -535,7 +539,7 @@ Can be overridden.
-
Returns void
+Defined in src/pools/abstract-pool.ts:1438
Protected
checkDynamicPoolSize
@@ -550,7 +554,7 @@ Can be overridden.
max: number
Returns void
+Defined in src/pools/abstract-pool.ts:187
Private
checkFilePath
@@ -563,7 +567,7 @@ Can be overridden.
filePath: string
Returns void
+Defined in src/pools/abstract-pool.ts:156
Private
checkMessageWorkerId
+Defined in src/pools/abstract-pool.ts:565
Private
checkNumberOfWorkers
@@ -597,7 +601,7 @@ Can be overridden.
numberOfWorkers: number
Returns void
+Defined in src/pools/abstract-pool.ts:169
Private
checkPoolOptions
@@ -610,7 +614,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:213
Private
checkValidTasksQueueOptions
@@ -623,7 +627,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:304
Private
checkValidWorkerChoiceStrategy
@@ -636,7 +640,7 @@ Can be overridden.
workerChoiceStrategy: "ROUND_ROBIN" | "LEAST_USED" | "LEAST_BUSY" | "LEAST_ELU" | "FAIR_SHARE" | "WEIGHTED_ROUND_ROBIN" | "INTERLEAVED_WEIGHTED_ROUND_ROBIN"
Returns void
+Defined in src/pools/abstract-pool.ts:244
Private
checkValidWorkerChoiceStrategyOptions
@@ -649,7 +653,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:257
Private
chooseWorkerNode
@@ -662,7 +666,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:1062
Protected
createAndSetupDynamicWorkerNode
@@ -674,7 +678,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:1152
Protected
createAndSetupWorkerNode
@@ -686,7 +690,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:1108
Protected
Abstract
createWorker
@@ -698,7 +702,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:1101
Private
dequeueTask
@@ -711,7 +715,7 @@ Can be overridden.
workerNodeKey: number
Returns undefined | Task<Data>
+Defined in src/pools/abstract-pool.ts:1534
+Defined in src/pools/abstract-pool.ts:850
Protected
Abstract
destroyWorkerNode
@@ -742,7 +746,7 @@ Can be overridden.
Returns Promise<void>
+Defined in src/pools/abstract-pool.ts:881
+Defined in src/pools/abstract-pool.ts:636
Private
enqueueTask
@@ -782,7 +786,7 @@ Can be overridden.
task: Task<Data>
Returns number
+Defined in src/pools/abstract-pool.ts:1528
+Defined in src/pools/abstract-pool.ts:779
Private
executeTask
@@ -837,7 +841,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:1522
Protected
flushTasksQueue
@@ -850,7 +854,7 @@ Can be overridden.
workerNodeKey: number
Returns void
+Defined in src/pools/abstract-pool.ts:1542
Private
flushTasksQueues
@@ -858,7 +862,7 @@ Can be overridden.
-
Returns void
+Defined in src/pools/abstract-pool.ts:1552
Protected
getWorkerInfo
@@ -878,7 +882,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:1458
Private
getWorkerNodeKeyByWorker
@@ -898,7 +902,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:584
Private
getWorkerNodeKeyByWorkerId
@@ -918,7 +922,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:596
Private
handleTaskExecutionResponse
@@ -931,7 +935,7 @@ Can be overridden.
message: MessageValue<Response, unknown>
Returns void
+Defined in src/pools/abstract-pool.ts:1404
Private
handleWorkerReadyResponse
@@ -944,7 +948,7 @@ Can be overridden.
message: MessageValue<Response, unknown>
Returns void
+Defined in src/pools/abstract-pool.ts:1390
Private
hasBackPressure
@@ -952,7 +956,7 @@ Can be overridden.
-
Returns boolean
+Defined in src/pools/abstract-pool.ts:1507
hasWorkerNodeBackPressure
+Defined in src/pools/abstract-pool.ts:1500
Protected
internalBusy
@@ -985,7 +989,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:738
Protected
Abstract
isMain
@@ -996,7 +1000,7 @@ Can be overridden.
Returns boolean
+Defined in src/pools/abstract-pool.ts:896
+Defined in src/pools/abstract-pool.ts:758
Private
redistributeQueuedTasks
@@ -1022,7 +1026,7 @@ Can be overridden.
workerNodeKey: number
Returns void
+Defined in src/pools/abstract-pool.ts:1253
Protected
Abstract
registerWorkerMessageListener
@@ -1062,7 +1066,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:1196
Private
removeWorkerNode
@@ -1081,7 +1085,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:1491
Protected
sendKillMessageToWorker
@@ -1096,7 +1100,7 @@ Can be overridden.
workerId: number
Returns Promise<void>
+Defined in src/pools/abstract-pool.ts:860
Protected
Abstract
sendStartupMessageToWorker
@@ -1115,7 +1119,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:1233
Private
sendStatisticsMessageToWorker
@@ -1134,7 +1138,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:1240
Protected
Abstract
sendToWorker
@@ -1163,7 +1167,15 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:1090
+
+Private
setTaskStealing
+
+- setTaskStealing(): void
+-
+
Returns void
+Defined in src/pools/abstract-pool.ts:650
Private
setTasksQueueSize
@@ -1196,7 +1208,15 @@ Can be overridden.
size: number
Returns void
+Defined in src/pools/abstract-pool.ts:685
+
+Private
setTasksStealingOnBackPressure
+
+- setTasksStealingOnBackPressure(): void
+-
+
Returns void
+Defined in src/pools/abstract-pool.ts:603
setWorkerChoiceStrategyOptions
+Defined in src/pools/abstract-pool.ts:622
Protected
setupHook
@@ -1253,7 +1273,7 @@ Can be overridden.
Returns void
+Defined in src/pools/abstract-pool.ts:889
Private
shallCreateDynamicWorker
@@ -1265,7 +1285,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:1079
Private
shallExecuteTask
@@ -1278,7 +1298,7 @@ Can be overridden.
workerNodeKey: number
Returns boolean
+Defined in src/pools/abstract-pool.ts:770
Private
shallUpdateTaskFunctionWorkerUsage
@@ -1298,15 +1318,19 @@ Can be overridden.
-
+
+start
+
+- start(): void
-
-
Returns void
+Defined in src/pools/abstract-pool.ts:834
Private
taskStealingOnEmptyQueue
@@ -1319,7 +1343,7 @@ Can be overridden.
workerId: number
Returns void
+Defined in src/pools/abstract-pool.ts:1297
Private
tasksQueueSize
@@ -1332,7 +1356,7 @@ Can be overridden.
workerNodeKey: number
Returns number
+Defined in src/pools/abstract-pool.ts:1538
Private
tasksStealingOnBackPressure
@@ -1345,7 +1369,23 @@ Can be overridden.
workerId: number
Returns void
+Defined in src/pools/abstract-pool.ts:1329
+
+Private
unsetTaskStealing
+
+- unsetTaskStealing(): void
+-
+
Returns void
+
+Private
unsetTasksStealingOnBackPressure
+
+- unsetTasksStealingOnBackPressure(): void
+-
+
Returns void
Private
updateEluWorkerUsage
@@ -1360,7 +1400,7 @@ Can be overridden.
message: MessageValue<Response, unknown>
Returns void
+Defined in src/pools/abstract-pool.ts:1022
Private
updateRunTimeWorkerUsage
@@ -1375,7 +1415,7 @@ Can be overridden.
message: MessageValue<Response, unknown>
Returns void
+Defined in src/pools/abstract-pool.ts:995
Private
updateTaskStatisticsWorkerUsage
@@ -1390,7 +1430,7 @@ Can be overridden.
message: MessageValue<Response, unknown>
Returns void
+Defined in src/pools/abstract-pool.ts:977
Private
updateTaskStolenStatisticsWorkerUsage
@@ -1405,7 +1445,7 @@ Can be overridden.
taskName: string
Returns void
+Defined in src/pools/abstract-pool.ts:1278
Private
updateWaitTimeWorkerUsage
@@ -1420,7 +1460,7 @@ Can be overridden.
task: Task<Data>
Returns void
+Defined in src/pools/abstract-pool.ts:1009
Protected
workerListener
@@ -1447,7 +1487,7 @@ Can be overridden.
+Defined in src/pools/abstract-pool.ts:1372
+
Defined in src/worker/abstract-worker.ts:73
Protected
Abstract
id
id: number
@@ -172,7 +172,7 @@
+Defined in src/worker/abstract-worker.ts:57
Protected
Readonly
isMain
isMain: boolean
@@ -180,7 +180,7 @@
+Defined in src/worker/abstract-worker.ts:85
Protected
lastTaskTimestamp
lastTaskTimestamp: number
@@ -188,7 +188,7 @@
+Defined in src/worker/abstract-worker.ts:65
Private
Readonly
mainWorker
mainWorker: MainWorker
@@ -196,7 +196,7 @@
+Defined in src/worker/abstract-worker.ts:86
Protected
opts
@@ -204,7 +204,7 @@
+Defined in src/worker/abstract-worker.ts:88
Protected
statistics
@@ -212,7 +212,7 @@
+Defined in src/worker/abstract-worker.ts:69
Protected
taskFunctions
@@ -220,7 +220,7 @@
+Defined in src/worker/abstract-worker.ts:61
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:307
Private
beginTaskPerformance
@@ -278,7 +278,7 @@ If a task function with the same name already exists, it is replaced.
Optional
name: string
+Defined in src/worker/abstract-worker.ts:601
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:284
Private
checkActive
@@ -316,7 +316,7 @@ If a task function with the same name already exists, it is replaced.
Returns void
+Defined in src/worker/abstract-worker.ts:446
Private
checkMessageWorkerId
+Defined in src/worker/abstract-worker.ts:412
Private
checkStatistics
@@ -345,7 +345,7 @@ If a task function with the same name already exists, it is replaced.
-
Returns void
+Defined in src/worker/abstract-worker.ts:625
Private
checkTaskFunctionName
@@ -358,13 +358,13 @@ If a task function with the same name already exists, it is replaced.
name: string
Returns void
+Defined in src/worker/abstract-worker.ts:335
Private
checkTaskFunctions
- checkTaskFunctions(taskFunctions): void
-
-
+Defined in src/worker/abstract-worker.ts:610
+Defined in src/worker/abstract-worker.ts:461
Protected
handleError
-- handleError(e): string
+- handleError(error): string
-
@@ -460,7 +460,7 @@ never be called.
Parameters
-
-
e: string | Error
+error: string | Error
@@ -468,7 +468,7 @@ never be called.
+Defined in src/worker/abstract-worker.ts:493
Protected
handleKillMessage
@@ -487,7 +487,7 @@ never be called.
Returns void
+Defined in src/worker/abstract-worker.ts:378
Protected
Abstract
handleReadyMessage
@@ -506,7 +506,7 @@ never be called.
Returns void
+Defined in src/worker/abstract-worker.ts:349
+Defined in src/worker/abstract-worker.ts:204
listTaskFunctions
@@ -540,7 +540,7 @@ never be called.
+Defined in src/worker/abstract-worker.ts:282
Protected
messageListener
@@ -559,7 +559,7 @@ never be called.
Returns void
+Defined in src/worker/abstract-worker.ts:356
+Defined in src/worker/abstract-worker.ts:258
+Defined in src/worker/abstract-worker.ts:503
Protected
runAsync
@@ -630,7 +630,7 @@ never be called.
Returns void
+Defined in src/worker/abstract-worker.ts:567
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:295
Protected
runSync
@@ -709,7 +709,7 @@ then restore the original execution context.
Returns void
+Defined in src/worker/abstract-worker.ts:531
Protected
sendTaskFunctionsListToMainWorker
@@ -720,7 +720,7 @@ then restore the original execution context.
Returns void
+Defined in src/worker/abstract-worker.ts:480
Protected
Abstract
sendToMainWorker
@@ -739,7 +739,7 @@ then restore the original execution context.
Returns void
+Defined in src/worker/abstract-worker.ts:473
+Defined in src/worker/abstract-worker.ts:312
Private
startCheckActive
@@ -776,7 +776,7 @@ then restore the original execution context.
Returns void
+Defined in src/worker/abstract-worker.ts:425
Private
stopCheckActive
@@ -787,7 +787,7 @@ then restore the original execution context.
Returns void
+Defined in src/worker/abstract-worker.ts:436
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:312
Private
updateLastTaskTimestamp
@@ -806,7 +806,7 @@ then restore the original execution context.
-
Returns void
+Defined in src/worker/abstract-worker.ts:631
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:278
@@ -31,7 +31,7 @@
+
Defined in src/circular-array.ts:10
+
Defined in src/circular-array.ts:13
Properties
@@ -153,7 +153,7 @@ when they will be absent when used in a 'with' statement.
size
size: number
+Defined in src/circular-array.ts:11
Static
Readonly
[species]
[species]: ArrayConstructor
Returns void
+
Defined in src/circular-array.ts:100
concat
@@ -222,7 +222,7 @@ when they will be absent when used in a 'with' statement.
Inherit Doc
+Defined in src/circular-array.ts:41
copyWithin
@@ -263,7 +263,7 @@ is treated as length+end.
-
Returns boolean
+Defined in src/circular-array.ts:92
entries
@@ -729,7 +729,7 @@ thisArg is omitted, undefined is used as the this value.
-
Returns boolean
+Defined in src/circular-array.ts:96
includes
@@ -910,7 +910,7 @@ If the array is empty, undefined is returned and the array is not modified.
Inherit Doc
+Defined in src/circular-array.ts:23
reduce
@@ -1145,7 +1145,7 @@ If the array is empty, undefined is returned and the array is not modified.
size: number
Returns void
+Defined in src/circular-array.ts:80
reverse
@@ -1301,7 +1301,7 @@ value otherwise. If omitted, the elements are sorted in ascending, ASCII charact
Inherit Doc
+Defined in src/circular-array.ts:56
toLocaleString
@@ -1341,7 +1341,7 @@ value otherwise. If omitted, the elements are sorted in ascending, ASCII charact
Inherit Doc
+Defined in src/circular-array.ts:32
values
@@ -1599,7 +1599,7 @@ value otherwise. If omitted, the elements are sorted in ascending, ASCII charact
- isArray
- of
@@ -47,7 +47,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/cluster-worker.ts:21
@@ -127,7 +127,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/cluster-worker.ts:31
Protected
Readonly
isMain
isMain: boolean
@@ -147,7 +147,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:85
Protected
lastTaskTimestamp
lastTaskTimestamp: number
@@ -156,7 +156,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:65
Protected
opts
@@ -165,7 +165,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:88
Protected
statistics
@@ -174,7 +174,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:69
Protected
taskFunctions
@@ -183,7 +183,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:61
Accessors
@@ -197,7 +197,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/cluster-worker.ts:65
Methods
@@ -232,7 +232,7 @@ If a task function with the same name already exists, it is replaced.
+
Defined in src/worker/abstract-worker.ts:220
+
Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:307
bind
@@ -270,7 +270,7 @@ If a task function with the same name already exists, it is replaced.
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:284
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:303
+Defined in src/worker/abstract-worker.ts:461
Protected
handleError
-- handleError(e): string
+- handleError(error): string
-
@@ -313,7 +313,7 @@ never be called.
Parameters
-
-
e: string | Error
+error: string | Error
@@ -322,7 +322,7 @@ never be called.
+Defined in src/worker/abstract-worker.ts:493
Protected
handleKillMessage
+Defined in src/worker/abstract-worker.ts:378
Protected
handleReadyMessage
+Defined in src/worker/cluster-worker.ts:45
+Defined in src/worker/abstract-worker.ts:204
+Defined in src/worker/abstract-worker.ts:282
Protected
messageListener
+Defined in src/worker/abstract-worker.ts:356
+Defined in src/worker/abstract-worker.ts:258
+Defined in src/worker/abstract-worker.ts:503
+Defined in src/worker/abstract-worker.ts:567
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:295
+Defined in src/worker/abstract-worker.ts:531
Protected
sendTaskFunctionsListToMainWorker
+Defined in src/worker/abstract-worker.ts:480
Protected
sendToMainWorker
+Defined in src/worker/cluster-worker.ts:70
+Defined in src/worker/abstract-worker.ts:312
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:312
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:278
@@ -33,7 +33,7 @@ Implemented with a doubly linked list.
+
Defined in src/deque.ts:26
@@ -77,14 +77,14 @@ Implemented with a doubly linked list.
T
Returns Deque<T>
+
Defined in src/deque.ts:34
maxSize
maxSize: number
@@ -92,7 +92,7 @@ Implemented with a doubly linked list.
+
Defined in src/deque.ts:32
size
size: number
@@ -100,12 +100,12 @@ Implemented with a doubly linked list.
+Defined in src/deque.ts:30
+Defined in src/deque.ts:28
+Defined in src/deque.ts:170
clear
@@ -146,7 +146,7 @@ Implemented with a doubly linked list.
Returns void
+Defined in src/deque.ts:131
Private
incrementSize
@@ -154,7 +154,7 @@ Implemented with a doubly linked list.
-
Returns number
+Defined in src/deque.ts:194
peekFirst
@@ -166,7 +166,7 @@ Implemented with a doubly linked list.
+Defined in src/deque.ts:116
peekLast
@@ -178,7 +178,7 @@ Implemented with a doubly linked list.
+Defined in src/deque.ts:124
pop
@@ -190,7 +190,7 @@ Implemented with a doubly linked list.
+Defined in src/deque.ts:77
push
@@ -210,7 +210,7 @@ Implemented with a doubly linked list.
+Defined in src/deque.ts:44
shift
@@ -222,7 +222,7 @@ Implemented with a doubly linked list.
+Defined in src/deque.ts:97
unshift
@@ -242,7 +242,7 @@ Implemented with a doubly linked list.
+Defined in src/deque.ts:61
@@ -45,7 +45,7 @@ When the maximum number of workers is reached and workers are busy, an event is
+
Defined in src/pools/cluster/dynamic.ts:15
@@ -150,7 +151,7 @@ When the maximum number of workers is reached and workers are busy, an event is
+Defined in src/pools/cluster/dynamic.ts:27
Properties
@@ -171,7 +172,7 @@ When the maximum number of workers is reached and workers are busy, an event is
+Defined in src/pools/abstract-pool.ts:68
Protected
Readonly
filePath
filePath: string
@@ -180,7 +181,7 @@ When the maximum number of workers is reached and workers are busy, an event is
+Defined in src/pools/abstract-pool.ts:116
Protected
Readonly
max
max: number
@@ -189,7 +190,7 @@ When the maximum number of workers is reached and workers are busy, an event is
+Defined in src/pools/cluster/dynamic.ts:29
Protected
Readonly
numberOfWorkers
numberOfWorkers: number
@@ -198,7 +199,7 @@ When the maximum number of workers is reached and workers are busy, an event is
+Defined in src/pools/abstract-pool.ts:115
Protected
Readonly
opts
@@ -207,11 +208,11 @@ When the maximum number of workers is reached and workers are busy, an event is
+Defined in src/pools/cluster/fixed.ts:47
Protected
promiseResponseMap
-
@@ -45,7 +45,7 @@ When the maximum number of threads is reached and workers are busy, an event is
+
Defined in src/pools/thread/dynamic.ts:15
@@ -150,7 +151,7 @@ When the maximum number of threads is reached and workers are busy, an event is
+Defined in src/pools/thread/dynamic.ts:27
Properties
@@ -171,7 +172,7 @@ When the maximum number of threads is reached and workers are busy, an event is
+Defined in src/pools/abstract-pool.ts:68
Protected
Readonly
filePath
filePath: string
@@ -180,7 +181,7 @@ When the maximum number of threads is reached and workers are busy, an event is
+Defined in src/pools/abstract-pool.ts:116
Protected
Readonly
max
max: number
@@ -189,7 +190,7 @@ When the maximum number of threads is reached and workers are busy, an event is
+Defined in src/pools/thread/dynamic.ts:29
Protected
Readonly
numberOfWorkers
numberOfWorkers: number
@@ -198,7 +199,7 @@ When the maximum number of threads is reached and workers are busy, an event is
+Defined in src/pools/abstract-pool.ts:115
Protected
Readonly
opts
@@ -207,11 +208,11 @@ When the maximum number of threads is reached and workers are busy, an event is
+Defined in src/pools/thread/fixed.ts:49
+Defined in src/pools/cluster/fixed.ts:44
Protected
Readonly
filePath
filePath: string
@@ -175,7 +176,7 @@
+Defined in src/pools/abstract-pool.ts:116
Protected
Optional
Readonly
max
max?: number
@@ -184,7 +185,7 @@
+Defined in src/pools/abstract-pool.ts:92
Protected
Readonly
numberOfWorkers
numberOfWorkers: number
@@ -193,7 +194,7 @@
+Defined in src/pools/abstract-pool.ts:115
Protected
Readonly
opts
@@ -202,11 +203,11 @@
+Defined in src/pools/cluster/fixed.ts:47
+Defined in src/pools/thread/fixed.ts:46
Protected
Readonly
filePath
filePath: string
@@ -175,7 +176,7 @@
+Defined in src/pools/abstract-pool.ts:116
Protected
Optional
Readonly
max
max?: number
@@ -184,7 +185,7 @@
+Defined in src/pools/abstract-pool.ts:92
Protected
Readonly
numberOfWorkers
numberOfWorkers: number
@@ -193,7 +194,7 @@
+Defined in src/pools/abstract-pool.ts:115
Protected
Readonly
opts
@@ -202,11 +203,11 @@
+Defined in src/pools/thread/fixed.ts:49
@@ -26,7 +26,7 @@
+
Defined in src/pools/pool.ts:39
+
Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:109
+
Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:390
Static
captureRejections
captureRejections: boolean
@@ -109,7 +109,7 @@
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:397
Static
defaultMaxListeners
defaultMaxListeners: number
@@ -140,7 +140,7 @@ Its name
property is set to 'MaxListenersExceededWarning&
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:434
Static
Readonly
errorMonitor
@@ -153,7 +153,7 @@ regular 'error'
listener is installed.
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:383
Methods
@@ -187,7 +187,7 @@ regular 'error'
listener is installed.
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:454
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:716
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:779
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:631
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:725
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:644
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:604
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:486
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:516
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:743
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:759
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:675
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:615
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:599
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:625
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:375
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:296
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:325
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:268
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:250
Static
once
once(emitter, eventName, options?): Promise<any[]>
@@ -844,7 +844,7 @@ special handling:
Returns Promise<any[]>
+
Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:190
Static
setMaxListeners
@@ -869,7 +869,7 @@ special handling:
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/events.d.ts:340
@@ -47,7 +47,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/thread-worker.ts:26
@@ -128,7 +128,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/thread-worker.ts:40
Protected
Readonly
isMain
isMain: boolean
@@ -148,7 +148,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:85
Protected
lastTaskTimestamp
lastTaskTimestamp: number
@@ -157,7 +157,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:65
Protected
opts
@@ -166,7 +166,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:88
Private
port
port: MessagePort
@@ -174,7 +174,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/thread-worker.ts:33
Protected
statistics
@@ -183,7 +183,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:69
Protected
taskFunctions
@@ -192,7 +192,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/abstract-worker.ts:61
Accessors
@@ -206,7 +206,7 @@ but the minimum number of workers will be guaranteed.
+
Defined in src/worker/thread-worker.ts:86
Methods
@@ -241,7 +241,7 @@ If a task function with the same name already exists, it is replaced.
+Defined in src/worker/abstract-worker.ts:220
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:307
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:284
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:303
+Defined in src/worker/abstract-worker.ts:461
Protected
handleError
-- handleError(e): string
+- handleError(error): string
-
@@ -322,7 +322,7 @@ never be called.
Parameters
-
-
e: string | Error
+error: string | Error
@@ -331,7 +331,7 @@ never be called.
+Defined in src/worker/thread-worker.ts:96
Protected
handleKillMessage
+Defined in src/worker/thread-worker.ts:79
Protected
handleReadyMessage
+Defined in src/worker/thread-worker.ts:54
+Defined in src/worker/abstract-worker.ts:204
+Defined in src/worker/abstract-worker.ts:282
Protected
messageListener
+Defined in src/worker/abstract-worker.ts:356
+Defined in src/worker/abstract-worker.ts:258
+Defined in src/worker/abstract-worker.ts:503
+Defined in src/worker/abstract-worker.ts:567
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:295
+Defined in src/worker/abstract-worker.ts:531
Protected
sendTaskFunctionsListToMainWorker
+Defined in src/worker/abstract-worker.ts:480
Protected
sendToMainWorker
+Defined in src/worker/thread-worker.ts:91
+Defined in src/worker/abstract-worker.ts:312
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:312
+Defined in node_modules/.pnpm/@types+node@20.6.2/node_modules/@types/node/async_hooks.d.ts:278
+
Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:52
Private
retriesCount
retriesCount: number = 0
@@ -126,12 +126,12 @@
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:40
Private
Readonly
workerChoiceStrategies
workerChoiceStrategies: Map<"ROUND_ROBIN" | "LEAST_USED" | "LEAST_BUSY" | "LEAST_ELU" | "FAIR_SHARE" | "WEIGHTED_ROUND_ROBIN" | "INTERLEAVED_WEIGHTED_ROUND_ROBIN", IWorkerChoiceStrategy>
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:32
Private
workerChoiceStrategy
workerChoiceStrategy: "ROUND_ROBIN" | "LEAST_USED" | "LEAST_BUSY" | "LEAST_ELU" | "FAIR_SHARE" | "WEIGHTED_ROUND_ROBIN" | "INTERLEAVED_WEIGHTED_ROUND_ROBIN" = WorkerChoiceStrategies.ROUND_ROBIN
@@ -139,7 +139,7 @@
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:51
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:119
getTaskStatisticsRequirements
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:132
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:200
setOptions
@@ -218,7 +218,7 @@
Returns void
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:213
setWorkerChoiceStrategy
@@ -237,7 +237,7 @@
Returns void
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:145
+Defined in src/pools/selection-strategies/worker-choice-strategy-context.ts:159
@@ -26,7 +26,7 @@ Always returns a value greater than zero.
+
Defined in src/utils.ts:56
-
poolifier - v2.6.44
+
poolifier - v2.6.45
Index
@@ -110,7 +110,7 @@
Theme
@@ -26,7 +26,7 @@
+
Defined in src/pools/cluster/fixed.ts:10
+
Defined in src/pools/pool.ts:185
Optional
enableTasksQueue
enableTasksQueue?: boolean
@@ -72,7 +73,7 @@
+Defined in src/pools/pool.ts:191
+Defined in src/pools/cluster/fixed.ts:16
+Defined in src/pools/pool.ts:153
+Defined in src/pools/pool.ts:159
Optional
messageHandler
-
+Defined in src/pools/pool.ts:147
+Defined in src/pools/pool.ts:141
Optional
restartWorkerOnError
restartWorkerOnError?: boolean
@@ -127,7 +136,7 @@
+Defined in src/pools/pool.ts:179
+Defined in src/pools/cluster/fixed.ts:22
+
+Optional
startWorkers
+startWorkers?: boolean
+
+
Optional
tasksQueueOptions
@@ -146,7 +167,7 @@
+Defined in src/pools/pool.ts:195
Optional
workerChoiceStrategy
workerChoiceStrategy?: "ROUND_ROBIN" | "LEAST_USED" | "LEAST_BUSY" | "LEAST_ELU" | "FAIR_SHARE" | "WEIGHTED_ROUND_ROBIN" | "INTERLEAVED_WEIGHTED_ROUND_ROBIN"
@@ -158,7 +179,7 @@
+Defined in src/pools/pool.ts:171
Optional
workerChoiceStrategyOptions
@@ -167,7 +188,7 @@
+Defined in src/pools/pool.ts:175
@@ -24,7 +24,7 @@
- EventLoopUtilizationMeasurementStatistics
+
Defined in src/pools/worker.ts:71
+
Defined in src/pools/worker.ts:72
Optional
utilization
utilization?: number
+
Defined in src/pools/worker.ts:74
@@ -46,7 +46,7 @@
+
Defined in src/pools/pool.ts:205
@@ -83,7 +84,7 @@
Returns Promise<void>
+Defined in src/pools/pool.ts:262
Optional
Readonly
emitter
@@ -101,7 +102,7 @@
+Defined in src/pools/pool.ts:241
Readonly
enableTasksQueue
enableTasksQueue: ((enable, tasksQueueOptions?) => void)
@@ -130,7 +131,7 @@
Returns void
+Defined in src/pools/pool.ts:293
Readonly
execute
execute: ((data?, name?, transferList?) => Promise<Response>)
@@ -165,7 +166,7 @@
+Defined in src/pools/pool.ts:250
Readonly
hasWorkerNodeBackPressure
hasWorkerNodeBackPressure: ((workerNodeKey) => boolean)
@@ -190,7 +191,7 @@
+Defined in src/pools/pool.ts:227
Readonly
info
@@ -198,7 +199,7 @@
+Defined in src/pools/pool.ts:213
Readonly
listTaskFunctions
listTaskFunctions: (() => string[])
@@ -215,7 +216,7 @@
+Defined in src/pools/pool.ts:268
Readonly
setTasksQueueOptions
setTasksQueueOptions: ((tasksQueueOptions) => void)
@@ -239,7 +240,7 @@
Returns void
+Defined in src/pools/pool.ts:302
Readonly
setWorkerChoiceStrategy
setWorkerChoiceStrategy: ((workerChoiceStrategy, workerChoiceStrategyOptions?) => void)
@@ -268,7 +269,7 @@
Returns void
+Defined in src/pools/pool.ts:275
Readonly
setWorkerChoiceStrategyOptions
setWorkerChoiceStrategyOptions: ((workerChoiceStrategyOptions) => void)
@@ -292,7 +293,23 @@
Returns void
+Defined in src/pools/pool.ts:284
+
+Readonly
start
+start: (() => void)
+
+
Type declaration
+
+-
+
+- (): void
+-
+
+
Returns void
+
Readonly
Internal
workerNodes
@@ -300,7 +317,7 @@
+Defined in src/pools/pool.ts:219
@@ -24,7 +24,7 @@
+
Defined in src/pools/worker.ts:186
+
Defined in src/pools/worker.ts:190
Readonly
on
on: ((event, handler) => void) & ((event, handler) => void) & ((event, handler) => void) & ((event, handler) => void)
@@ -118,7 +118,7 @@
Param
The event handler.
+Defined in src/pools/worker.ts:198
Readonly
once
once: ((event, handler) => void)
@@ -147,12 +147,12 @@
Returns void
+Defined in src/pools/worker.ts:208
Optional
Readonly
threadId
threadId?: number
+Defined in src/pools/worker.ts:191
@@ -24,7 +24,7 @@
+
Defined in src/pools/selection-strategies/selection-strategies-types.ts:168
@@ -59,7 +59,7 @@ If the worker node is not eligible, undefined
is returned.
+
Defined in src/pools/selection-strategies/selection-strategies-types.ts:195
Readonly
remove
remove: ((workerNodeKey) => boolean)
@@ -84,7 +84,7 @@ If the worker node is not eligible, undefined
is returned.
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:202
Readonly
reset
reset: (() => boolean)
@@ -101,7 +101,7 @@ If the worker node is not eligible, undefined
is returned.
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:182
Readonly
setOptions
setOptions: ((opts) => void)
@@ -125,7 +125,7 @@ If the worker node is not eligible, undefined
is returned.
Returns void
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:208
Readonly
strategyPolicy
@@ -133,7 +133,7 @@ If the worker node is not eligible, undefined
is returned.
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:172
Readonly
taskStatisticsRequirements
@@ -141,7 +141,7 @@ If the worker node is not eligible, undefined
is returned.
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:176
Readonly
update
update: ((workerNodeKey) => boolean)
@@ -163,7 +163,7 @@ If the worker node is not eligible, undefined
is returned.
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:188
@@ -37,7 +37,7 @@
+
Defined in src/pools/worker.ts:226
@@ -81,7 +81,7 @@
Returns void
+
Defined in src/pools/worker.ts:296
Readonly
closeChannel
closeChannel: (() => void)
@@ -97,7 +97,7 @@
Returns void
+Defined in src/pools/worker.ts:310
Readonly
dequeueTask
dequeueTask: (() => undefined | Task<Data>)
@@ -114,7 +114,7 @@
+Defined in src/pools/worker.ts:286
Readonly
enqueueTask
enqueueTask: ((task) => number)
@@ -139,7 +139,7 @@
+Defined in src/pools/worker.ts:273
Readonly
getTaskFunctionWorkerUsage
getTaskFunctionWorkerUsage: ((name) => undefined | WorkerUsage)
@@ -164,7 +164,7 @@
+Defined in src/pools/worker.ts:317
Readonly
hasBackPressure
hasBackPressure: (() => boolean)
@@ -181,7 +181,7 @@
+Defined in src/pools/worker.ts:302
Readonly
info
@@ -189,7 +189,7 @@
+Defined in src/pools/worker.ts:234
Optional
Readonly
messageChannel
messageChannel?: MessageChannel
@@ -197,7 +197,7 @@
+Defined in src/pools/worker.ts:247
Optional
onBackPressure
@@ -205,7 +205,7 @@
+Defined in src/pools/worker.ts:256
Optional
onEmptyQueue
@@ -213,7 +213,7 @@
+Defined in src/pools/worker.ts:260
Readonly
popTask
popTask: (() => undefined | Task<Data>)
@@ -230,7 +230,7 @@
+Defined in src/pools/worker.ts:292
Readonly
resetUsage
resetUsage: (() => void)
@@ -246,7 +246,7 @@
Returns void
+Defined in src/pools/worker.ts:306
Optional
strategyData
@@ -255,7 +255,7 @@ This is used to store data that is specific to the worker choice strategy.
+Defined in src/pools/worker.ts:243
tasksQueueBackPressureSize
tasksQueueBackPressureSize: number
@@ -264,7 +264,7 @@ This is the number of tasks that can be enqueued before the worker node has back
+Defined in src/pools/worker.ts:252
Readonly
tasksQueueSize
tasksQueueSize: (() => number)
@@ -281,7 +281,7 @@ This is the number of tasks that can be enqueued before the worker node has back
+Defined in src/pools/worker.ts:266
Readonly
unshiftTask
unshiftTask: ((task) => number)
@@ -306,7 +306,7 @@ This is the number of tasks that can be enqueued before the worker node has back
+Defined in src/pools/worker.ts:280
Readonly
usage
@@ -314,7 +314,7 @@ This is the number of tasks that can be enqueued before the worker node has back
+Defined in src/pools/worker.ts:238
Readonly
worker
worker: Worker
@@ -322,7 +322,7 @@ This is the number of tasks that can be enqueued before the worker node has back
+Defined in src/pools/worker.ts:230
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:63
@@ -24,7 +24,7 @@
+
Defined in src/pools/worker.ts:39
+
Defined in src/pools/worker.ts:43
Optional
average
average?: number
@@ -56,7 +56,7 @@
+Defined in src/pools/worker.ts:55
Readonly
history
@@ -64,7 +64,7 @@
+Defined in src/pools/worker.ts:63
Optional
maximum
maximum?: number
@@ -72,7 +72,7 @@
+Defined in src/pools/worker.ts:51
Optional
median
median?: number
@@ -80,7 +80,7 @@
+Defined in src/pools/worker.ts:59
Optional
minimum
minimum?: number
@@ -88,7 +88,7 @@
+Defined in src/pools/worker.ts:47
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:120
median
median: boolean
@@ -61,7 +61,7 @@
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:124
@@ -39,7 +39,7 @@
+
Defined in src/utility-types.ts:105
+
Defined in src/utility-types.ts:134
Optional
Readonly
data
data?: Data
@@ -80,7 +80,7 @@
+
Defined in src/utility-types.ts:83
Optional
Readonly
kill
kill?: true | "success" | "SOFT" | "HARD" | "failure"
@@ -88,7 +88,7 @@
+Defined in src/utility-types.ts:110
Optional
Readonly
name
name?: string
@@ -97,7 +97,7 @@
+Defined in src/utility-types.ts:79
Optional
Readonly
port
port?: MessagePort
@@ -105,7 +105,7 @@
+Defined in src/utility-types.ts:138
Optional
Readonly
ready
ready?: boolean
@@ -113,7 +113,7 @@
+Defined in src/utility-types.ts:130
Optional
Readonly
statistics
@@ -121,7 +121,7 @@
+Defined in src/utility-types.ts:126
Optional
Readonly
taskError
@@ -129,7 +129,7 @@
+Defined in src/utility-types.ts:114
Optional
Readonly
taskFunctions
taskFunctions?: string[]
@@ -137,7 +137,7 @@
+Defined in src/utility-types.ts:122
Optional
Readonly
taskId
taskId?: string
@@ -146,7 +146,7 @@
+Defined in src/utility-types.ts:95
Optional
Readonly
taskPerformance
@@ -154,7 +154,7 @@
+Defined in src/utility-types.ts:118
Optional
Readonly
timestamp
timestamp?: number
@@ -163,7 +163,7 @@
+Defined in src/utility-types.ts:91
Optional
Readonly
transferList
transferList?: TransferListItem[]
@@ -172,7 +172,7 @@
+Defined in src/utility-types.ts:87
Readonly
workerId
workerId: number
@@ -181,7 +181,7 @@
+Defined in src/utility-types.ts:75
@@ -24,7 +24,7 @@
+
Defined in src/pools/pool.ts:62
Readonly
busyWorkerNodes
busyWorkerNodes: number
@@ -67,22 +68,22 @@
+
Defined in src/pools/pool.ts:78
Readonly
executedTasks
executedTasks: number
+
Defined in src/pools/pool.ts:79
Readonly
executingTasks
executingTasks: number
+
Defined in src/pools/pool.ts:80
Readonly
failedTasks
failedTasks: number
+
Defined in src/pools/pool.ts:85
Readonly
idleWorkerNodes
idleWorkerNodes: number
@@ -90,32 +91,32 @@
+Defined in src/pools/pool.ts:76
Optional
Readonly
maxQueuedTasks
maxQueuedTasks?: number
+Defined in src/pools/pool.ts:82
Readonly
maxSize
maxSize: number
+Defined in src/pools/pool.ts:70
Readonly
minSize
minSize: number
+Defined in src/pools/pool.ts:69
Optional
Readonly
queuedTasks
queuedTasks?: number
+Defined in src/pools/pool.ts:81
Readonly
ready
ready: boolean
+Defined in src/pools/pool.ts:67
Optional
Readonly
runTime
runTime?: {
    average?: number;
    maximum: number;
    median?: number;
    minimum: number;
}
@@ -131,22 +132,27 @@
Readonly
minimum: number
+Defined in src/pools/pool.ts:86
+
+Readonly
started
+started: boolean
Optional
Readonly
stolenTasks
stolenTasks?: number
+Defined in src/pools/pool.ts:84
Readonly
strategy
strategy: "ROUND_ROBIN" | "LEAST_USED" | "LEAST_BUSY" | "LEAST_ELU" | "FAIR_SHARE" | "WEIGHTED_ROUND_ROBIN" | "INTERLEAVED_WEIGHTED_ROUND_ROBIN"
+Defined in src/pools/pool.ts:68
Readonly
type
type: "fixed" | "dynamic"
+Defined in src/pools/pool.ts:64
Optional
Readonly
utilization
utilization?: number
@@ -154,12 +160,12 @@
+Defined in src/pools/pool.ts:72
Readonly
version
version: string
+Defined in src/pools/pool.ts:63
Optional
Readonly
waitTime
waitTime?: {
    average?: number;
    maximum: number;
    median?: number;
    minimum: number;
}
@@ -175,12 +181,12 @@
Readonly
minimum: number
+Defined in src/pools/pool.ts:92
Readonly
worker
worker: "thread" | "cluster"
+Defined in src/pools/pool.ts:65
Readonly
workerNodes
workerNodes: number
@@ -188,7 +194,7 @@
+Defined in src/pools/pool.ts:74
+
Defined in src/pools/pool.ts:185
Optional
enableTasksQueue
enableTasksQueue?: boolean
@@ -77,39 +78,47 @@
+Defined in src/pools/pool.ts:191
+Defined in src/pools/pool.ts:153
+Defined in src/pools/pool.ts:159
Optional
messageHandler
-
+Defined in src/pools/pool.ts:147
+Defined in src/pools/pool.ts:141
Optional
restartWorkerOnError
restartWorkerOnError?: boolean
@@ -117,7 +126,18 @@
+Defined in src/pools/pool.ts:179
+
+Optional
startWorkers
+startWorkers?: boolean
+
+
Optional
tasksQueueOptions
@@ -125,7 +145,7 @@
+Defined in src/pools/pool.ts:195
Optional
workerChoiceStrategy
workerChoiceStrategy?: "ROUND_ROBIN" | "LEAST_USED" | "LEAST_BUSY" | "LEAST_ELU" | "FAIR_SHARE" | "WEIGHTED_ROUND_ROBIN" | "INTERLEAVED_WEIGHTED_ROUND_ROBIN"
@@ -136,7 +156,7 @@
+Defined in src/pools/pool.ts:171
Optional
workerChoiceStrategyOptions
@@ -144,7 +164,7 @@
+Defined in src/pools/pool.ts:175
@@ -32,7 +32,7 @@
+
Defined in src/utility-types.ts:147
@@ -66,7 +66,7 @@
Returns void
+
Defined in src/utility-types.ts:155
Readonly
resolve
resolve: ((value) => void)
@@ -87,7 +87,7 @@
Returns void
+Defined in src/utility-types.ts:151
Readonly
workerNodeKey
workerNodeKey: number
@@ -95,7 +95,7 @@
+Defined in src/utility-types.ts:159
@@ -24,7 +24,7 @@
+
Defined in src/pools/worker.ts:179
@@ -40,7 +40,7 @@
Optional
virtualTaskEndTimestamp
virtualTaskEndTimestamp?: number
+
Defined in src/pools/worker.ts:180
+
Defined in src/pools/selection-strategies/selection-strategies-types.ts:160
Readonly
dynamicWorkerUsage
dynamicWorkerUsage: boolean
@@ -52,7 +52,7 @@
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:156
@@ -34,7 +34,7 @@
+
Defined in src/utility-types.ts:71
+
Defined in src/utility-types.ts:83
Optional
Readonly
name
name?: string
@@ -66,7 +66,7 @@
+Defined in src/utility-types.ts:79
Optional
Readonly
taskId
taskId?: string
@@ -74,7 +74,7 @@
+Defined in src/utility-types.ts:95
Optional
Readonly
timestamp
timestamp?: number
@@ -82,7 +82,7 @@
+Defined in src/utility-types.ts:91
Optional
Readonly
transferList
transferList?: TransferListItem[]
@@ -90,7 +90,7 @@
+Defined in src/utility-types.ts:87
Readonly
workerId
workerId: number
@@ -98,7 +98,7 @@
+Defined in src/utility-types.ts:75
@@ -32,7 +32,7 @@
+
Defined in src/utility-types.ts:10
+
Defined in src/utility-types.ts:22
Readonly
message
message: string
@@ -61,7 +61,7 @@
+Defined in src/utility-types.ts:18
Readonly
name
name: string
@@ -69,7 +69,7 @@
+Defined in src/utility-types.ts:14
@@ -24,7 +24,7 @@
+
Defined in src/utility-types.ts:30
+
Defined in src/utility-types.ts:46
Readonly
name
name: string
@@ -54,7 +54,7 @@
+Defined in src/utility-types.ts:34
Optional
Readonly
runTime
runTime?: number
@@ -62,7 +62,7 @@
+Defined in src/utility-types.ts:42
Readonly
timestamp
timestamp: number
@@ -70,7 +70,7 @@
+Defined in src/utility-types.ts:38
@@ -24,7 +24,7 @@
+
Defined in src/pools/worker.ts:82
+
Defined in src/pools/worker.ts:86
executing
executing: number
@@ -56,7 +56,7 @@
+Defined in src/pools/worker.ts:90
failed
failed: number
@@ -64,7 +64,7 @@
+Defined in src/pools/worker.ts:106
Optional
Readonly
maxQueued
maxQueued?: number
@@ -72,7 +72,7 @@
+Defined in src/pools/worker.ts:98
Readonly
queued
queued: number
@@ -80,7 +80,7 @@
+Defined in src/pools/worker.ts:94
stolen
stolen: number
@@ -88,7 +88,7 @@
+Defined in src/pools/worker.ts:102
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:136
Readonly
waitTime
@@ -61,7 +61,7 @@
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:140
@@ -24,7 +24,7 @@
+
Defined in src/pools/pool.ts:103
Properties
@@ -48,15 +49,7 @@
-
-Optional
Readonly
queueMaxSize
-queueMaxSize?: number
-
+Defined in src/pools/pool.ts:115
Optional
Readonly
size
size?: number
@@ -67,7 +60,29 @@
+Defined in src/pools/pool.ts:109
+
+Optional
Readonly
taskStealing
+taskStealing?: boolean
+
+
+
+Optional
Readonly
tasksStealingOnBackPressure
+tasksStealingOnBackPressure?: boolean
+
+
@@ -26,7 +26,7 @@
+
Defined in src/pools/thread/fixed.ts:18
+
Defined in src/pools/pool.ts:185
Optional
enableTasksQueue
enableTasksQueue?: boolean
@@ -71,43 +72,51 @@
+Defined in src/pools/pool.ts:191
+Defined in src/pools/pool.ts:153
+Defined in src/pools/pool.ts:159
Optional
messageHandler
-
+Defined in src/pools/pool.ts:147
+Defined in src/pools/pool.ts:141
Optional
restartWorkerOnError
restartWorkerOnError?: boolean
@@ -116,7 +125,19 @@
+Defined in src/pools/pool.ts:179
+
+Optional
startWorkers
+startWorkers?: boolean
+
+
Optional
tasksQueueOptions
@@ -125,7 +146,7 @@
+Defined in src/pools/pool.ts:195
Optional
workerChoiceStrategy
workerChoiceStrategy?: "ROUND_ROBIN" | "LEAST_USED" | "LEAST_BUSY" | "LEAST_ELU" | "FAIR_SHARE" | "WEIGHTED_ROUND_ROBIN" | "INTERLEAVED_WEIGHTED_ROUND_ROBIN"
@@ -137,7 +158,7 @@
+Defined in src/pools/pool.ts:171
Optional
workerChoiceStrategyOptions
@@ -146,7 +167,7 @@
+Defined in src/pools/pool.ts:175
+Defined in src/pools/thread/fixed.ts:24
+
Defined in src/pools/selection-strategies/selection-strategies-types.ts:97
Optional
Readonly
measurement
measurement?: "runTime" | "waitTime" | "elu"
@@ -59,7 +59,7 @@
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:79
Optional
Readonly
retries
retries?: number
@@ -70,7 +70,7 @@
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:75
Optional
Readonly
runTime
@@ -81,7 +81,7 @@
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:85
Optional
Readonly
waitTime
@@ -92,7 +92,7 @@
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:91
Optional
Readonly
weights
weights?: Record<number, number>
@@ -104,7 +104,7 @@ A weight is tasks maximum execution time in milliseconds for a worker node.
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:104
@@ -24,7 +24,7 @@
+
Defined in src/pools/worker.ts:127
+
Defined in src/pools/worker.ts:139
Readonly
id
id: undefined | number
@@ -55,7 +55,7 @@
+Defined in src/pools/worker.ts:131
ready
ready: boolean
@@ -63,7 +63,7 @@
+Defined in src/pools/worker.ts:143
Optional
taskFunctions
taskFunctions?: string[]
@@ -71,7 +71,7 @@
+Defined in src/pools/worker.ts:147
Readonly
type
type: "thread" | "cluster"
@@ -79,7 +79,7 @@
+Defined in src/pools/worker.ts:135
@@ -24,7 +24,7 @@
+
Defined in src/worker/worker-options.ts:28
@@ -51,7 +51,7 @@
Deprecated
This option will be removed in the next major version.
+
Defined in src/worker/worker-options.ts:65
Optional
killBehavior
killBehavior?: "SOFT" | "HARD"
@@ -67,19 +67,21 @@
+Defined in src/worker/worker-options.ts:39
+Defined in src/worker/worker-options.ts:58
@@ -24,7 +24,7 @@
+
Defined in src/utility-types.ts:54
+
Defined in src/utility-types.ts:62
Readonly
runTime
runTime: boolean
@@ -52,7 +52,7 @@
+Defined in src/utility-types.ts:58
@@ -24,7 +24,7 @@
+
Defined in src/pools/worker.ts:155
+
Defined in src/pools/worker.ts:171
Readonly
runTime
@@ -54,7 +54,7 @@
+Defined in src/pools/worker.ts:163
Readonly
tasks
@@ -62,7 +62,7 @@
+Defined in src/pools/worker.ts:159
Readonly
waitTime
@@ -70,7 +70,7 @@
+Defined in src/pools/worker.ts:167
@@ -40,7 +40,7 @@
Returns void
+Defined in src/pools/worker.ts:21
@@ -40,7 +40,7 @@
Returns void
+Defined in src/pools/worker.ts:29
+Defined in src/worker/worker-options.ts:18
@@ -28,7 +28,7 @@
Returns void | Promise<void>
+Defined in src/worker/worker-options.ts:23
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:54
@@ -40,7 +40,7 @@
Returns void
+Defined in src/pools/worker.ts:13
@@ -38,7 +38,7 @@
Returns void
+Defined in src/pools/worker.ts:8
+Defined in src/pools/pool.ts:57
+Defined in src/pools/pool.ts:34
@@ -47,7 +47,7 @@ This function must return a promise.
Returns Promise<Response>
+Defined in src/worker/task-functions.ts:18
@@ -34,7 +34,7 @@ This function can be synchronous or asynchronous.
+
Defined in src/worker/task-functions.ts:29
@@ -36,7 +36,7 @@ The value is the function itself.
+
Defined in src/worker/task-functions.ts:42
@@ -46,7 +46,7 @@
Returns Response
+Defined in src/worker/task-functions.ts:7
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:40
@@ -36,7 +36,7 @@
Returns void
+Defined in src/pools/worker.ts:217
+Defined in src/pools/worker.ts:120
+Defined in src/worker/worker-options.ts:4
@@ -29,7 +29,7 @@
Readonly
waitTime: "waitTime"
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:45
@@ -37,7 +37,7 @@
Readonly
taskError: "taskError"
+Defined in src/pools/pool.ts:44
+Defined in src/pools/pool.ts:20
+Defined in src/pools/selection-strategies/selection-strategies-types.ts:4
@@ -27,7 +27,7 @@
Readonly
thread: "thread"
+Defined in src/pools/worker.ts:112
The task execution response promise map.
+The task execution response promise map:
key
: The message id of each submitted task.value
: An object that contains the worker, the execution response promise resolve and reject callbacks.Private
Readonly
start