### Breaking Changes
-- maxInactiveTime default behavior is now changed, if you want to keep the old behavior set killBehavior to HARD ( Find more details on our JSDoc ).
+- `maxInactiveTime` default behavior is now changed, if you want to keep the old behavior set `killBehavior` to `KillBehaviors.HARD`.
+ _Find more details on our JSDoc._
- We changed some internal structures, but you shouldn't be too affected by them as these are internal changes.
},
"dependencies": {
"globals": {
- "version": "13.5.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.5.0.tgz",
- "integrity": "sha512-TMJe2Iu/qCIEFnG7IQ62C9N/iKdgX5wSvmGOVuk75+UAGDW+Yv/hH5+Ky6d/8UMqo4WCzhFCy+pHsvv09zhBoQ==",
+ "version": "13.6.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.6.0.tgz",
+ "integrity": "sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
"dev": true
},
"handlebars": {
- "version": "4.7.6",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
- "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
+ "version": "4.7.7",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
+ "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
"dev": true,
"requires": {
"minimist": "^1.2.5",
export { AbstractWorker } from './worker/abstract-worker'
export { ClusterWorker } from './worker/cluster-worker'
export { ThreadWorker } from './worker/thread-worker'
-export type { WorkerOptions } from './worker/worker-options'
-export { killBehaviorTypes } from './worker/worker-options'
+export { KillBehaviors } from './worker/worker-options'
+export type { KillBehavior, WorkerOptions } from './worker/worker-options'
import type { Worker } from 'cluster'
import type { JSONValue } from '../../utility-types'
+import { isKillBehavior, KillBehaviors } from '../../worker/worker-options'
import type { ClusterPoolOptions } from './fixed'
import { FixedClusterPool } from './fixed'
-import { killBehaviorTypes } from '../../worker/worker-options'
/**
* A cluster pool with a dynamic number of workers, but a guaranteed minimum number of workers.
const workerCreated = this.createAndSetupWorker()
this.registerWorkerMessageListener<Data>(workerCreated, message => {
const tasksInProgress = this.tasks.get(workerCreated)
- const isKillBehaviorOptionHard = message.kill === killBehaviorTypes.HARD
- if (isKillBehaviorOptionHard || tasksInProgress === 0) {
+ if (
+ isKillBehavior(KillBehaviors.HARD, message.kill) ||
+ tasksInProgress === 0
+ ) {
// Kill received from the worker, means that no new tasks are submitted to that worker for a while ( > maxInactiveTime)
this.sendToWorker(workerCreated, { kill: 1 })
void this.destroyWorker(workerCreated)
import type { JSONValue } from '../../utility-types'
+import { isKillBehavior, KillBehaviors } from '../../worker/worker-options'
import type { PoolOptions } from '../abstract-pool'
import type { ThreadWorkerWithMessageChannel } from './fixed'
import { FixedThreadPool } from './fixed'
-import { killBehaviorTypes } from '../../worker/worker-options'
/**
* A thread pool with a dynamic number of threads, but a guaranteed minimum number of threads.
const workerCreated = this.createAndSetupWorker()
this.registerWorkerMessageListener<Data>(workerCreated, message => {
const tasksInProgress = this.tasks.get(workerCreated)
- const isKillBehaviorOptionHard = message.kill === killBehaviorTypes.HARD
- if (isKillBehaviorOptionHard || tasksInProgress === 0) {
+ if (
+ isKillBehavior(KillBehaviors.HARD, message.kill) ||
+ tasksInProgress === 0
+ ) {
// Kill received from the worker, means that no new tasks are submitted to that worker for a while ( > maxInactiveTime)
this.sendToWorker(workerCreated, { kill: 1 })
void this.destroyWorker(workerCreated)
import type { Worker } from 'cluster'
import type { MessagePort } from 'worker_threads'
+import type { KillBehavior } from './worker/worker-options'
-export type KillBehavior = 'HARD' | 'SOFT'
/**
* Make all properties in T non-readonly
*/
/**
* Kill code.
*/
- readonly kill?: KillBehavior | number
+ readonly kill?: KillBehavior | 1
/**
* Error.
*/
import { AsyncResource } from 'async_hooks'
import type { Worker } from 'cluster'
import type { MessagePort } from 'worker_threads'
-import type { MessageValue, KillBehavior } from '../utility-types'
-import type { WorkerOptions } from './worker-options'
+import type { MessageValue } from '../utility-types'
+import type { KillBehavior, WorkerOptions } from './worker-options'
+import { KillBehaviors } from './worker-options'
-const defaultMaxInactiveTime = 1000 * 60
-// TODO fix this and avoid that SOFT/HARD words are replicated so much times into the project
-const defaultKillBehavior: KillBehavior = 'SOFT'
+const DEFAULT_MAX_INACTIVE_TIME = 1000 * 60
+const DEFAULT_KILL_BEHAVIOR: KillBehavior = KillBehaviors.SOFT
/**
* Base class containing some shared logic for all poolifier workers.
fn: (data: Data) => Response,
protected mainWorker?: MainWorker | null,
public readonly opts: WorkerOptions = {
- killBehavior: defaultKillBehavior,
- maxInactiveTime: defaultMaxInactiveTime
+ killBehavior: DEFAULT_KILL_BEHAVIOR,
+ maxInactiveTime: DEFAULT_MAX_INACTIVE_TIME
}
) {
super(type)
- this.killBehavior = this.opts.killBehavior ?? defaultKillBehavior
- this.maxInactiveTime = this.opts.maxInactiveTime ?? defaultMaxInactiveTime
+ this.killBehavior = this.opts.killBehavior ?? DEFAULT_KILL_BEHAVIOR
+ this.maxInactiveTime =
+ this.opts.maxInactiveTime ?? DEFAULT_MAX_INACTIVE_TIME
this.async = !!this.opts.async
this.lastTask = Date.now()
if (!fn) throw new Error('fn parameter is mandatory')
-import type { KillBehavior } from '../utility-types'
-
/**
- * Kill behavior enumeration
+ * Enumeration of kill behaviors.
*/
-export const killBehaviorTypes = Object.freeze({
+export const KillBehaviors = Object.freeze({
+ /**
+ * If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker **wont** be deleted.
+ */
SOFT: 'SOFT',
+ /**
+ * If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
+ */
HARD: 'HARD'
-})
+} as const)
+
+/**
+ * Kill behavior.
+ */
+export type KillBehavior = keyof typeof KillBehaviors
+
+/**
+ * Detects whether the given value is a kill behavior or not.
+ *
+ * @template KB Which specific KillBehavior to test against.
+ * @param killBehavior Which kind of kill behavior to detect. Default: `KillBehaviors.HARD`.
+ * @param value Any value.
+ * @returns `true` if `value` was strictly equals to `killBehavior`, otherwise `false`.
+ */
+export function isKillBehavior<KB extends KillBehavior> (
+ killBehavior: KB,
+ value: unknown
+): value is KB {
+ return value === killBehavior
+}
/**
* Options for workers.
export interface WorkerOptions {
/**
* Maximum waiting time in milliseconds for tasks.
+ *
* After this time, newly created workers will be terminated.
* The last active time of your worker unit will be updated when a task is submitted to a worker or when a worker terminate a task.
- * If killBehavior is set to HARD this value represents also the timeout for the tasks that you submit to the pool,
- * when this timeout expires your tasks is interrupted and the worker is killed if is not part of the minimum size of the pool.
- * If killBehavior is set to SOFT your tasks have no timeout and your workers will not be terminated until your task is
+ *
+ * - 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 and 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.
*
* @default 60.000 ms
*/
*/
async?: boolean
/**
- * killBehavior dictates if your async unit ( worker/process ) will be deleted in case that a task is active on it.
- * SOFT: If current time - last active time is greater than maxInactiveTime option, but a task is still running then the worker will be not deleted.
- * HARD: If last active time is greater than maxInactiveTime option, but a task is still running then the worker will be deleted.
+ * `killBehavior` dictates if your async unit (worker/process) will be deleted in case that a task is active on it.
+ *
+ * - SOFT: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker **wont** be deleted.
+ * - HARD: If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
+ *
* This option only apply to the newly created workers.
*
- * @default SOFT
+ * @default KillBehaviors.SOFT
*/
killBehavior?: KillBehavior
}
'use strict'
-const { ClusterWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ClusterWorker, KillBehaviors } = require('../../../lib/index')
async function error (data) {
return new Promise((resolve, reject) => {
module.exports = new ClusterWorker(error, {
maxInactiveTime: 500,
async: true,
- killBehavior: killBehaviorTypes
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ClusterWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ClusterWorker, KillBehaviors } = require('../../../lib/index')
async function sleep (data) {
return new Promise((resolve, reject) => {
module.exports = new ClusterWorker(sleep, {
maxInactiveTime: 500,
async: true,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ClusterWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ClusterWorker, KillBehaviors } = require('../../../lib/index')
function echo (data) {
return data
module.exports = new ClusterWorker(echo, {
maxInactiveTime: 500,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ClusterWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ClusterWorker, KillBehaviors } = require('../../../lib/index')
function test (data) {}
module.exports = new ClusterWorker(test, {
maxInactiveTime: 500,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ClusterWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ClusterWorker, KillBehaviors } = require('../../../lib/index')
function error (data) {
throw new Error('Error Message from ClusterWorker')
module.exports = new ClusterWorker(error, {
maxInactiveTime: 500,
async: false,
- killBehavior: killBehaviorTypes
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ClusterWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ClusterWorker, KillBehaviors } = require('../../../lib/index')
async function sleep (data) {
return new Promise((resolve, reject) => {
module.exports = new ClusterWorker(sleep, {
maxInactiveTime: 500,
async: true,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ClusterWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ClusterWorker, KillBehaviors } = require('../../../lib/index')
const { isMaster } = require('cluster')
function test (data) {
module.exports = new ClusterWorker(test, {
maxInactiveTime: 500,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ThreadWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ThreadWorker, KillBehaviors } = require('../../../lib/index')
async function sleep (data) {
return new Promise((resolve, reject) => {
module.exports = new ThreadWorker(sleep, {
maxInactiveTime: 500,
async: true,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ThreadWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ThreadWorker, KillBehaviors } = require('../../../lib/index')
function echo (data) {
return data
module.exports = new ThreadWorker(echo, {
maxInactiveTime: 500,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ThreadWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ThreadWorker, KillBehaviors } = require('../../../lib/index')
function test (data) {}
module.exports = new ThreadWorker(test, {
maxInactiveTime: 500,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ThreadWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ThreadWorker, KillBehaviors } = require('../../../lib/index')
function error (data) {
throw new Error(data)
module.exports = new ThreadWorker(error, {
maxInactiveTime: 500,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ThreadWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ThreadWorker, KillBehaviors } = require('../../../lib/index')
async function sleep (data) {
return new Promise((resolve, reject) => {
module.exports = new ThreadWorker(sleep, {
maxInactiveTime: 500,
async: true,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})
'use strict'
-const { ThreadWorker, killBehaviorTypes } = require('../../../lib/index')
+const { ThreadWorker, KillBehaviors } = require('../../../lib/index')
const { isMainThread } = require('worker_threads')
function test (data) {
module.exports = new ThreadWorker(test, {
maxInactiveTime: 500,
- killBehavior: killBehaviorTypes.HARD
+ killBehavior: KillBehaviors.HARD
})