## [Unreleased]
+### Fixed
+
+- Ensure cluster pool destroy() gracefully shutdowns worker's server.
+- Ensure pool event is emitted before task error promise rejection.
+
## [2.6.3] - 2023-06-19
### Fixed
"lib"
],
"devDependencies": {
- "@commitlint/cli": "^17.6.5",
- "@commitlint/config-conventional": "^17.6.5",
+ "@commitlint/cli": "^17.6.6",
+ "@commitlint/config-conventional": "^17.6.6",
"@release-it/bumper": "^4.0.2",
"@release-it/keep-a-changelog": "^3.1.0",
"@rollup/plugin-terser": "^0.4.3",
devDependencies:
'@commitlint/cli':
- specifier: ^17.6.5
- version: 17.6.5
+ specifier: ^17.6.6
+ version: 17.6.6
'@commitlint/config-conventional':
- specifier: ^17.6.5
- version: 17.6.5
+ specifier: ^17.6.6
+ version: 17.6.6
'@release-it/bumper':
specifier: ^4.0.2
version: 4.0.2(release-it@15.11.0)
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: true
- /@commitlint/cli@17.6.5:
- resolution: {integrity: sha512-3PQrWr/uo6lzF5k7n5QuosCYnzaxP9qGBp3jhWP0Vmsa7XA6wrl9ccPqfQyXpSbQE3zBROVO3TDqgPKe4tfmLQ==}
+ /@commitlint/cli@17.6.6:
+ resolution: {integrity: sha512-sTKpr2i/Fjs9OmhU+beBxjPavpnLSqZaO6CzwKVq2Tc4UYVTMFgpKOslDhUBVlfAUBfjVO8ParxC/MXkIOevEA==}
engines: {node: '>=v14'}
hasBin: true
dependencies:
'@commitlint/format': 17.4.4
- '@commitlint/lint': 17.6.5
+ '@commitlint/lint': 17.6.6
'@commitlint/load': 17.5.0
'@commitlint/read': 17.5.1
'@commitlint/types': 17.4.4
- '@swc/wasm'
dev: true
- /@commitlint/config-conventional@17.6.5:
- resolution: {integrity: sha512-Xl9H9KLl86NZm5CYNTNF9dcz1xelE/EbvhWIWcYxG/rn3UWYWdWmmnX2q6ZduNdLFSGbOxzUpIx61j5zxbeXxg==}
+ /@commitlint/config-conventional@17.6.6:
+ resolution: {integrity: sha512-phqPz3BDhfj49FUYuuZIuDiw+7T6gNAEy7Yew1IBHqSohVUCWOK2FXMSAExzS2/9X+ET93g0Uz83KjiHDOOFag==}
engines: {node: '>=v14'}
dependencies:
conventional-changelog-conventionalcommits: 5.0.0
chalk: 4.1.2
dev: true
- /@commitlint/is-ignored@17.6.5:
- resolution: {integrity: sha512-CQvAPt9gX7cuUbMrIaIMKczfWJqqr6m8IlJs0F2zYwyyMTQ87QMHIj5jJ5HhOaOkaj6dvTMVGx8Dd1I4xgUuoQ==}
+ /@commitlint/is-ignored@17.6.6:
+ resolution: {integrity: sha512-4Fw875faAKO+2nILC04yW/2Vy/wlV3BOYCSQ4CEFzriPEprc1Td2LILmqmft6PDEK5Sr14dT9tEzeaZj0V56Gg==}
engines: {node: '>=v14'}
dependencies:
'@commitlint/types': 17.4.4
- semver: 7.5.0
+ semver: 7.5.2
dev: true
- /@commitlint/lint@17.6.5:
- resolution: {integrity: sha512-BSJMwkE4LWXrOsiP9KoHG+/heSDfvOL/Nd16+ojTS/DX8HZr8dNl8l3TfVr/d/9maWD8fSegRGtBtsyGuugFrw==}
+ /@commitlint/lint@17.6.6:
+ resolution: {integrity: sha512-5bN+dnHcRLkTvwCHYMS7Xpbr+9uNi0Kq5NR3v4+oPNx6pYXt8ACuw9luhM/yMgHYwW0ajIR20wkPAFkZLEMGmg==}
engines: {node: '>=v14'}
dependencies:
- '@commitlint/is-ignored': 17.6.5
+ '@commitlint/is-ignored': 17.6.6
'@commitlint/parse': 17.6.5
'@commitlint/rules': 17.6.5
'@commitlint/types': 17.4.4
lodash.get: 4.4.2
lodash.set: 4.3.2
release-it: 15.11.0
- semver: 7.5.2
+ semver: 7.5.3
dev: true
/@release-it/keep-a-changelog@3.1.0(release-it@15.11.0):
grapheme-splitter: 1.0.4
ignore: 5.2.4
natural-compare-lite: 1.4.0
- semver: 7.5.2
+ semver: 7.5.3
tsutils: 3.21.0(typescript@5.1.3)
typescript: 5.1.3
transitivePeerDependencies:
debug: 4.3.4(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
- semver: 7.5.2
+ semver: 7.5.3
tsutils: 3.21.0(typescript@5.1.3)
typescript: 5.1.3
transitivePeerDependencies:
'@typescript-eslint/typescript-estree': 5.60.0(typescript@5.1.3)
eslint: 8.43.0
eslint-scope: 5.1.1
- semver: 7.5.2
+ semver: 7.5.3
transitivePeerDependencies:
- supports-color
- typescript
/builtins@5.0.1:
resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==}
dependencies:
- semver: 7.5.2
+ semver: 7.5.3
dev: true
/bundle-name@3.0.0:
engines: {node: '>=14.16'}
dev: true
- /cacheable-request@10.2.11:
- resolution: {integrity: sha512-kn0t0oJnlFo1Nzl/AYQzS/oByMtmaqLasFUa7MUMsiTrIHy8TxSkx2KzWCybE3Nuz1F4sJRGnLAfUGsPe47viQ==}
+ /cacheable-request@10.2.12:
+ resolution: {integrity: sha512-qtWGB5kn2OLjx47pYUkWicyOpK1vy9XZhq8yRTXOy+KAmjjESSRLx6SiExnnaGGUP1NM6/vmygMu0fGylNh9tw==}
engines: {node: '>=14.16'}
dependencies:
'@types/http-cache-semantics': 4.0.1
- get-stream: 7.0.0
+ get-stream: 6.0.1
http-cache-semantics: 4.1.1
keyv: 4.5.2
mimic-response: 4.0.0
eslint: 8.43.0
esquery: 1.5.0
is-builtin-module: 3.2.1
- semver: 7.5.2
+ semver: 7.5.3
spdx-expression-parse: 3.0.1
transitivePeerDependencies:
- supports-color
is-core-module: 2.12.1
minimatch: 3.1.2
resolve: 1.22.2
- semver: 7.5.2
+ semver: 7.5.3
dev: true
/eslint-plugin-n@16.0.0(eslint@8.43.0):
is-core-module: 2.12.1
minimatch: 3.1.2
resolve: 1.22.2
- semver: 7.5.2
+ semver: 7.5.3
dev: true
/eslint-plugin-promise@6.1.1(eslint@8.43.0):
engines: {node: '>=10'}
dev: true
- /get-stream@7.0.0:
- resolution: {integrity: sha512-ql6FW5b8tgMYvI4UaoxG3EQN3VyZ6VeQpxNBGg5BZ4xD4u+HJeprzhMMA4OCBEGQgSR+m87pstWMpiVW64W8Fw==}
- engines: {node: '>=16'}
- dev: true
-
/get-symbol-description@1.0.0:
resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
engines: {node: '>= 0.4'}
'@sindresorhus/is': 5.4.1
'@szmarczak/http-timer': 5.0.1
cacheable-lookup: 7.0.0
- cacheable-request: 10.2.11
+ cacheable-request: 10.2.12
decompress-response: 6.0.0
form-data-encoder: 2.1.4
get-stream: 6.0.1
brace-expansion: 2.0.1
dev: true
- /minimatch@9.0.1:
- resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
+ /minimatch@9.0.2:
+ resolution: {integrity: sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==}
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
brace-expansion: 2.0.1
dependencies:
hosted-git-info: 4.1.0
is-core-module: 2.12.1
- semver: 7.5.2
+ semver: 7.5.3
validate-npm-package-license: 3.0.4
dev: true
got: 12.6.1
registry-auth-token: 5.0.2
registry-url: 6.0.1
- semver: 7.5.2
+ semver: 7.5.3
dev: true
/parent-module@1.0.1:
resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==}
engines: {node: '>=12'}
dependencies:
- semver: 7.5.2
+ semver: 7.5.3
dev: true
/semver@5.7.1:
hasBin: true
dev: true
- /semver@7.5.0:
- resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==}
+ /semver@7.5.1:
+ resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==}
engines: {node: '>=10'}
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
- /semver@7.5.1:
- resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==}
+ /semver@7.5.2:
+ resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==}
engines: {node: '>=10'}
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
- /semver@7.5.2:
- resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==}
+ /semver@7.5.3:
+ resolution: {integrity: sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==}
engines: {node: '>=10'}
hasBin: true
dependencies:
dependencies:
lunr: 2.3.9
marked: 4.3.0
- minimatch: 9.0.1
+ minimatch: 9.0.2
shiki: 0.14.2
typescript: 5.1.3
dev: true
is-yarn-global: 0.4.1
latest-version: 7.0.0
pupa: 3.1.0
- semver: 7.5.2
+ semver: 7.5.3
semver-diff: 4.0.0
xdg-basedir: 5.1.0
dev: true
// The `busy` event is triggered when the number of submitted tasks at once reach the max number of workers in the dynamic pool.
// So in total numberOfWorkers + 1 times for a loop submitting up to numberOfWorkers * 2 tasks to the dynamic pool.
expect(poolBusy).toBe(max + 1)
- const numberOfExitEvents = await TestUtils.waitWorkerExits(pool, max - min)
+ const numberOfExitEvents = await TestUtils.waitWorkerEvents(
+ pool,
+ 'exit',
+ max - min
+ )
expect(numberOfExitEvents).toBe(max - min)
})
pool.execute()
}
expect(pool.workerNodes.length).toBeGreaterThan(min)
- await TestUtils.waitWorkerExits(pool, max - min)
+ await TestUtils.waitWorkerEvents(pool, 'exit', max - min)
expect(pool.workerNodes.length).toBe(min)
for (let i = 0; i < max * 2; i++) {
pool.execute()
}
expect(pool.workerNodes.length).toBeGreaterThan(min)
- await TestUtils.waitWorkerExits(pool, max - min)
+ await TestUtils.waitWorkerEvents(pool, 'exit', max - min)
expect(pool.workerNodes.length).toBe(min)
})
it('Shutdown test', async () => {
- const exitPromise = TestUtils.waitWorkerExits(pool, min)
+ const exitPromise = TestUtils.waitWorkerEvents(pool, 'exit', min)
await pool.destroy()
const numberOfExitEvents = await exitPromise
expect(numberOfExitEvents).toBe(min)
longRunningPool.execute()
}
expect(longRunningPool.workerNodes.length).toBe(max)
- await TestUtils.waitWorkerExits(longRunningPool, max - min)
+ await TestUtils.waitWorkerEvents(longRunningPool, 'exit', max - min)
expect(longRunningPool.workerNodes.length).toBe(min)
expect(
longRunningPool.workerChoiceStrategyContext.workerChoiceStrategies.get(
})
it('Shutdown test', async () => {
- const exitPromise = TestUtils.waitWorkerExits(pool, numberOfWorkers)
+ const exitPromise = TestUtils.waitWorkerEvents(
+ pool,
+ 'exit',
+ numberOfWorkers
+ )
await pool.destroy()
const numberOfExitEvents = await exitPromise
expect(numberOfExitEvents).toBe(numberOfWorkers)
// The `busy` event is triggered when the number of submitted tasks at once reach the max number of workers in the dynamic pool.
// So in total numberOfWorkers + 1 times for a loop submitting up to numberOfWorkers * 2 tasks to the dynamic pool.
expect(poolBusy).toBe(max + 1)
- const numberOfExitEvents = await TestUtils.waitWorkerExits(pool, max - min)
+ const numberOfExitEvents = await TestUtils.waitWorkerEvents(
+ pool,
+ 'exit',
+ max - min
+ )
expect(numberOfExitEvents).toBe(max - min)
})
pool.execute()
}
expect(pool.workerNodes.length).toBe(max)
- await TestUtils.waitWorkerExits(pool, max - min)
+ await TestUtils.waitWorkerEvents(pool, 'exit', max - min)
expect(pool.workerNodes.length).toBe(min)
for (let i = 0; i < max * 2; i++) {
pool.execute()
}
expect(pool.workerNodes.length).toBe(max)
- await TestUtils.waitWorkerExits(pool, max - min)
+ await TestUtils.waitWorkerEvents(pool, 'exit', max - min)
expect(pool.workerNodes.length).toBe(min)
})
it('Shutdown test', async () => {
- const exitPromise = TestUtils.waitWorkerExits(pool, min)
+ const exitPromise = TestUtils.waitWorkerEvents(pool, 'exit', min)
await pool.destroy()
const numberOfExitEvents = await exitPromise
expect(numberOfExitEvents).toBe(min)
longRunningPool.execute()
}
expect(longRunningPool.workerNodes.length).toBe(max)
- await TestUtils.waitWorkerExits(longRunningPool, max - min)
+ await TestUtils.waitWorkerEvents(longRunningPool, 'exit', max - min)
expect(longRunningPool.workerNodes.length).toBe(min)
expect(
longRunningPool.workerChoiceStrategyContext.workerChoiceStrategies.get(
})
it('Shutdown test', async () => {
- const exitPromise = TestUtils.waitWorkerExits(pool, numberOfThreads)
+ const exitPromise = TestUtils.waitWorkerEvents(
+ pool,
+ 'exit',
+ numberOfThreads
+ )
await pool.destroy()
const numberOfExitEvents = await exitPromise
expect(numberOfExitEvents).toBe(numberOfThreads)
const { WorkerFunctions } = require('./test-types')
class TestUtils {
- static async waitWorkerExits (pool, numberOfExitEventsToWait) {
+ static async waitWorkerEvents (pool, workerEvent, numberOfEventsToWait) {
return new Promise(resolve => {
- let exitEvents = 0
- if (numberOfExitEventsToWait === 0) {
- resolve(exitEvents)
+ let events = 0
+ if (numberOfEventsToWait === 0) {
+ resolve(events)
}
for (const workerNode of pool.workerNodes) {
- workerNode.worker.on('exit', () => {
- ++exitEvents
- if (exitEvents === numberOfExitEventsToWait) {
- resolve(exitEvents)
+ workerNode.worker.on(workerEvent, () => {
+ ++events
+ if (events === numberOfEventsToWait) {
+ resolve(events)
}
})
}