ecmaVersion: 2021,
sourceType: 'module'
},
- plugins: ['promise', 'jsdoc', 'spellcheck'],
+ plugins: ['promise', 'spellcheck'],
extends: [
'eslint:recommended',
'plugin:import/recommended',
- 'plugin:jsdoc/recommended',
'plugin:promise/recommended'
],
rules: {
'threadjs',
'threadwork',
'tsconfig',
+ 'tsdoc',
'typedoc',
'unlink',
'unregister',
overrides: [
{
files: ['**/*.ts'],
+ plugins: ['@typescript-eslint', 'eslint-plugin-tsdoc'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json'
},
- plugins: ['@typescript-eslint'],
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'no-useless-constructor': 'off',
- 'jsdoc/match-description': [
- 'warn',
- {
- contexts: ['any'],
- tags: {
- param: true,
- returns: true
- }
- }
- ],
- 'jsdoc/no-types': 'error',
- 'jsdoc/require-jsdoc': [
- 'warn',
- {
- contexts: [
- 'ClassDeclaration',
- 'ClassProperty:not([accessibility=/(private|protected)/])',
- 'ExportNamedDeclaration:has(VariableDeclaration)',
- 'FunctionExpression',
- 'MethodDefinition:not([accessibility=/(private|protected)/]) > FunctionExpression',
- 'TSEnumDeclaration',
- 'TSInterfaceDeclaration',
- 'TSMethodSignature',
- // 'TSPropertySignature',
- 'TSTypeAliasDeclaration'
- ]
- }
- ],
- 'jsdoc/require-param-type': 'off',
- 'jsdoc/require-returns-type': 'off'
+ 'tsdoc/syntax': 'warn'
}
},
{
files: ['examples/typescript/**/*.ts'],
rules: {
'import/no-unresolved': 'off',
- 'jsdoc/require-jsdoc': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off'
},
{
files: ['**/*.js'],
- extends: ['plugin:n/recommended', 'standard']
+ plugins: ['jsdoc'],
+ extends: ['plugin:n/recommended', 'standard', 'plugin:jsdoc/recommended']
},
{
files: ['tests/**/*.js'],
'jsdoc/require-jsdoc': 'off'
}
}
- ],
- settings: {
- jsdoc: {
- mode: 'typescript'
- }
- }
+ ]
})
"suchmokuo",
"threadjs",
"threadwork",
+ "tsdoc",
"workerpool"
],
"sonarlint.connectedMode.project": {
"eslint-plugin-n": "^15.6.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-spellcheck": "^0.0.20",
+ "eslint-plugin-tsdoc": "^0.2.17",
"expect": "^29.3.1",
"husky": "^8.0.2",
"lint-staged": "^13.1.0",
"integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==",
"dev": true
},
+ "node_modules/@microsoft/tsdoc": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
+ "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==",
+ "dev": true
+ },
+ "node_modules/@microsoft/tsdoc-config": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz",
+ "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==",
+ "dev": true,
+ "dependencies": {
+ "@microsoft/tsdoc": "0.14.2",
+ "ajv": "~6.12.6",
+ "jju": "~1.4.0",
+ "resolve": "~1.19.0"
+ }
+ },
+ "node_modules/@microsoft/tsdoc-config/node_modules/resolve": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+ "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.1.0",
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"eslint": ">=0.8.0"
}
},
+ "node_modules/eslint-plugin-tsdoc": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.17.tgz",
+ "integrity": "sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==",
+ "dev": true,
+ "dependencies": {
+ "@microsoft/tsdoc": "0.14.2",
+ "@microsoft/tsdoc-config": "0.16.2"
+ }
+ },
"node_modules/eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"node": ">= 10.13.0"
}
},
+ "node_modules/jju": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
+ "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
+ "dev": true
+ },
"node_modules/js-sdsl": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz",
"integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==",
"dev": true
},
+ "@microsoft/tsdoc": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
+ "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==",
+ "dev": true
+ },
+ "@microsoft/tsdoc-config": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz",
+ "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==",
+ "dev": true,
+ "requires": {
+ "@microsoft/tsdoc": "0.14.2",
+ "ajv": "~6.12.6",
+ "jju": "~1.4.0",
+ "resolve": "~1.19.0"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+ "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.1.0",
+ "path-parse": "^1.0.6"
+ }
+ }
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"lodash": "^4.17.15"
}
},
+ "eslint-plugin-tsdoc": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.17.tgz",
+ "integrity": "sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==",
+ "dev": true,
+ "requires": {
+ "@microsoft/tsdoc": "0.14.2",
+ "@microsoft/tsdoc-config": "0.16.2"
+ }
+ },
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"supports-color": "^7.0.0"
}
},
+ "jju": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
+ "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
+ "dev": true
+ },
"js-sdsl": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz",
"eslint-plugin-n": "^15.6.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-spellcheck": "^0.0.20",
+ "eslint-plugin-tsdoc": "^0.2.17",
"expect": "^29.3.1",
"husky": "^8.0.2",
"lint-staged": "^13.1.0",
/**
* Base class that implements some shared logic for all poolifier pools.
*
- * @template Worker Type of worker which manages this pool.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker which manages this pool.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export abstract class AbstractPool<
Worker extends IPoolWorker,
Data = unknown,
Response = unknown
> implements IPoolInternal<Worker, Data, Response> {
- /** @inheritDoc */
+ /** {@inheritDoc} */
public readonly workers: Worker[] = []
- /** @inheritDoc */
+ /** {@inheritDoc} */
public readonly workersTasksUsage: Map<Worker, TasksUsage> = new Map<
Worker,
TasksUsage
>()
- /** @inheritDoc */
+ /** {@inheritDoc} */
public readonly emitter?: PoolEmitter
/**
/**
* Constructs a new poolifier pool.
*
- * @param numberOfWorkers Number of workers that this pool should manage.
- * @param filePath Path to the worker-file.
- * @param opts Options for the pool.
+ * @param numberOfWorkers - Number of workers that this pool should manage.
+ * @param filePath - Path to the worker-file.
+ * @param opts - Options for the pool.
*/
public constructor (
public readonly numberOfWorkers: number,
this.opts.enableEvents = opts.enableEvents ?? true
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public abstract get type (): PoolType
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get numberOfRunningTasks (): number {
return this.promiseMap.size
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public getWorkerIndex (worker: Worker): number {
return this.workers.indexOf(worker)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public getWorkerRunningTasks (worker: Worker): number | undefined {
return this.workersTasksUsage.get(worker)?.running
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public getWorkerAverageTasksRunTime (worker: Worker): number | undefined {
return this.workersTasksUsage.get(worker)?.avgRunTime
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public setWorkerChoiceStrategy (
workerChoiceStrategy: WorkerChoiceStrategy
): void {
)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public abstract get busy (): boolean
protected internalGetBusyStatus (): boolean {
)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public findFreeWorker (): Worker | false {
for (const worker of this.workers) {
if (this.getWorkerRunningTasks(worker) === 0) {
return false
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public async execute (data: Data): Promise<Response> {
// Configure worker to handle message with the specified task
const worker = this.chooseWorker()
return res
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public async destroy (): Promise<void> {
await Promise.all(this.workers.map(worker => this.destroyWorker(worker)))
}
/**
* Shutdowns given worker.
*
- * @param worker A worker within `workers`.
+ * @param worker - A worker within `workers`.
*/
protected abstract destroyWorker (worker: Worker): void | Promise<void>
* Hook executed before the worker task promise resolution.
* Can be overridden.
*
- * @param worker The worker.
+ * @param worker - The worker.
*/
protected beforePromiseWorkerResponseHook (worker: Worker): void {
this.increaseWorkerRunningTasks(worker)
* Hook executed after the worker task promise resolution.
* Can be overridden.
*
- * @param message The received message.
- * @param promise The Promise response.
+ * @param message - The received message.
+ * @param promise - The Promise response.
*/
protected afterPromiseWorkerResponseHook (
message: MessageValue<Response>,
/**
* Removes the given worker from the pool.
*
- * @param worker The worker that will be removed.
+ * @param worker - The worker that will be removed.
*/
protected removeWorker (worker: Worker): void {
// Clean worker from data structure
/**
* Sends a message to the given worker.
*
- * @param worker The worker which should receive the message.
- * @param message The message.
+ * @param worker - The worker which should receive the message.
+ * @param message - The message.
*/
protected abstract sendToWorker (
worker: Worker,
/**
* Registers a listener callback on a given worker.
*
- * @param worker The worker which should register a listener.
- * @param listener The message listener callback.
+ * @param worker - The worker which should register a listener.
+ * @param listener - The message listener callback.
*/
protected abstract registerWorkerMessageListener<
Message extends Data | Response
/**
* Function that can be hooked up when a worker has been newly created and moved to the workers registry.
*
- * Can be used to update the `maxListeners` or binding the `main-worker`<->`worker` connection if not bind by default.
+ * Can be used to update the `maxListeners` or binding the `main-worker`\<-\>`worker` connection if not bind by default.
*
- * @param worker The newly created worker.
+ * @param worker - The newly created worker.
*/
protected abstract afterWorkerSetup (worker: Worker): void
/**
* Increases the number of tasks that the given worker has applied.
*
- * @param worker Worker which running tasks is increased.
+ * @param worker - Worker which running tasks is increased.
*/
private increaseWorkerRunningTasks (worker: Worker): void {
this.stepWorkerRunningTasks(worker, 1)
/**
* Decreases the number of tasks that the given worker has applied.
*
- * @param worker Worker which running tasks is decreased.
+ * @param worker - Worker which running tasks is decreased.
*/
private decreaseWorkerRunningTasks (worker: Worker): void {
this.stepWorkerRunningTasks(worker, -1)
/**
* Steps the number of tasks that the given worker has applied.
*
- * @param worker Worker which running tasks are stepped.
- * @param step Number of running tasks step.
+ * @param worker - Worker which running tasks are stepped.
+ * @param step - Number of running tasks step.
*/
private stepWorkerRunningTasks (worker: Worker, step: number): void {
if (this.checkWorkerTasksUsage(worker)) {
/**
* Steps the number of tasks that the given worker has run.
*
- * @param worker Worker which has run tasks.
- * @param step Number of run tasks step.
+ * @param worker - Worker which has run tasks.
+ * @param step - Number of run tasks step.
*/
private stepWorkerRunTasks (worker: Worker, step: number): void {
if (this.checkWorkerTasksUsage(worker)) {
/**
* Updates tasks runtime for the given worker.
*
- * @param worker Worker which run the task.
- * @param taskRunTime Worker task runtime.
+ * @param worker - Worker which run the task.
+ * @param taskRunTime - Worker task runtime.
*/
private updateWorkerTasksRunTime (
worker: Worker,
/**
* Checks if the given worker is registered in the workers tasks usage map.
*
- * @param worker Worker to check.
+ * @param worker - Worker to check.
* @returns `true` if the worker is registered in the workers tasks usage map. `false` otherwise.
*/
private checkWorkerTasksUsage (worker: Worker): boolean {
/**
* Initializes tasks usage statistics.
*
- * @param worker The worker.
+ * @param worker - The worker.
*/
private initWorkerTasksUsage (worker: Worker): void {
this.workersTasksUsage.set(worker, {
/**
* Removes worker tasks usage statistics.
*
- * @param worker The worker.
+ * @param worker - The worker.
*/
private removeWorkerTasksUsage (worker: Worker): void {
this.workersTasksUsage.delete(worker)
/**
* Resets worker tasks usage statistics.
*
- * @param worker The worker.
+ * @param worker - The worker.
*/
private resetWorkerTasksUsage (worker: Worker): void {
this.removeWorkerTasksUsage(worker)
* This cluster pool creates new workers when the others are busy, up to the maximum number of workers.
* When the maximum number of workers is reached, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
*
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
* @since 2.0.0
*/
/**
* Constructs a new poolifier dynamic cluster pool.
*
- * @param min Minimum number of workers which are always active.
- * @param max Maximum number of workers that can be created by this pool.
- * @param filePath Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.
- * @param opts Options for this dynamic cluster pool.
+ * @param min - Minimum number of workers which are always active.
+ * @param max - Maximum number of workers that can be created by this pool.
+ * @param filePath - Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.
+ * @param opts - Options for this dynamic cluster pool.
*/
public constructor (
min: number,
super(min, filePath, opts)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get type (): PoolType {
return PoolType.DYNAMIC
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get busy (): boolean {
return this.workers.length === this.max
}
*
* This pool selects the workers in a round robin fashion.
*
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
* @since 2.0.0
*/
/**
* Constructs a new poolifier fixed cluster pool.
*
- * @param numberOfWorkers Number of workers for this pool.
- * @param filePath Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.
- * @param opts Options for this fixed cluster pool.
+ * @param numberOfWorkers - Number of workers for this pool.
+ * @param filePath - Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.
+ * @param opts - Options for this fixed cluster pool.
*/
public constructor (
numberOfWorkers: number,
super(numberOfWorkers, filePath, opts)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected setupHook (): void {
cluster.setupPrimary({ ...this.opts.settings, exec: this.filePath })
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected isMain (): boolean {
return cluster.isPrimary
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public destroyWorker (worker: Worker): void {
this.sendToWorker(worker, { kill: 1 })
worker.kill()
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected sendToWorker (worker: Worker, message: MessageValue<Data>): void {
worker.send(message)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public registerWorkerMessageListener<Message extends Data | Response>(
worker: Worker,
listener: (message: MessageValue<Message>) => void
worker.on('message', listener)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected createWorker (): Worker {
return cluster.fork(this.opts.env)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected afterWorkerSetup (worker: Worker): void {
// Listen to worker messages.
this.registerWorkerMessageListener(worker, super.workerListener())
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get type (): PoolType {
return PoolType.FIXED
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get busy (): boolean {
return this.internalGetBusyStatus()
}
/**
* Internal contract definition for a poolifier pool.
*
- * @template Worker Type of worker which manages this pool.
- * @template Data Type of data sent to the worker.
- * @template Response Type of response of execution.
+ * @typeParam Worker - Type of worker which manages this pool.
+ * @typeParam Data - Type of data sent to the worker.
+ * @typeParam Response - Type of response of execution.
*/
export interface IPoolInternal<
Worker extends IPoolWorker,
/**
* Gets worker index.
*
- * @param worker The worker.
+ * @param worker - The worker.
* @returns The worker index.
*/
getWorkerIndex: (worker: Worker) => number
/**
* Gets worker running tasks.
*
- * @param worker The worker.
+ * @param worker - The worker.
* @returns The number of tasks currently running on the worker.
*/
getWorkerRunningTasks: (worker: Worker) => number | undefined
/**
* Gets worker average tasks runtime.
*
- * @param worker The worker.
+ * @param worker - The worker.
* @returns The average tasks runtime on the worker.
*/
getWorkerAverageTasksRunTime: (worker: Worker) => number | undefined
/**
* Register an event listener.
*
- * @param event The event.
- * @param handler The event listener.
+ * @param event - The event.
+ * @param handler - The event listener.
*/
on: ((event: 'message', handler: MessageHandler<this>) => void) &
((event: 'error', handler: ErrorHandler<this>) => void) &
/**
* Register a listener to the exit event that will only performed once.
*
- * @param event `'exit'`.
- * @param handler The exit handler.
+ * @param event - `'exit'`.
+ * @param handler - The exit handler.
*/
once: (event: 'exit', handler: ExitHandler<this>) => void
}
/**
* Pool events emission.
*
- * @default true
+ * @defaultValue true
*/
enableEvents?: boolean
}
/**
* Contract definition for a poolifier pool.
*
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export interface IPool<Data = unknown, Response = unknown> {
/**
/**
* Performs the task specified in the constructor with the data parameter.
*
- * @param data The input for the specified task. This can only be serializable data.
+ * @param data - The input for the specified task. This can only be serializable data.
* @returns Promise that will be resolved when the task is successfully completed.
*/
execute: (data: Data) => Promise<Response>
/**
* Sets the worker choice strategy in this pool.
*
- * @param workerChoiceStrategy The worker choice strategy.
+ * @param workerChoiceStrategy - The worker choice strategy.
*/
setWorkerChoiceStrategy: (workerChoiceStrategy: WorkerChoiceStrategy) => void
}
/**
* Abstract worker choice strategy class.
*
- * @template Worker Type of worker which manages the strategy.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker which manages the strategy.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export abstract class AbstractWorkerChoiceStrategy<
Worker extends IPoolWorker,
Data,
Response
> implements IWorkerChoiceStrategy<Worker> {
- /** @inheritDoc */
+ /** {@inheritDoc} */
public readonly isDynamicPool: boolean = this.pool.type === PoolType.DYNAMIC
- /** @inheritDoc */
+ /** {@inheritDoc} */
public requiredStatistics: RequiredStatistics = {
runTime: false
}
/**
* Constructs a worker choice strategy attached to the pool.
*
- * @param pool The pool instance.
+ * @param pool - The pool instance.
*/
public constructor (
protected readonly pool: IPoolInternal<Worker, Data, Response>
) {}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public abstract reset (): boolean
- /** @inheritDoc */
+ /** {@inheritDoc} */
public abstract choose (): Worker
}
/**
* Selects the next worker for dynamic pool.
*
- * @template Worker Type of worker which manages the strategy.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker which manages the strategy.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export class DynamicPoolWorkerChoiceStrategy<
Worker extends IPoolWorker,
/**
* Constructs a worker choice strategy for dynamic pool.
*
- * @param pool The pool instance.
- * @param createDynamicallyWorkerCallback The worker creation callback for dynamic pool.
- * @param workerChoiceStrategy The worker choice strategy when the pull is busy.
+ * @param pool - The pool instance.
+ * @param createDynamicallyWorkerCallback - The worker creation callback for dynamic pool.
+ * @param workerChoiceStrategy - The worker choice strategy when the pull is busy.
*/
public constructor (
pool: IPoolInternal<Worker, Data, Response>,
this.requiredStatistics = this.workerChoiceStrategy.requiredStatistics
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public reset (): boolean {
return this.workerChoiceStrategy.reset()
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public choose (): Worker {
const freeWorker = this.pool.findFreeWorker()
if (freeWorker !== false) {
* Selects the next worker with a fair share scheduling algorithm.
* Loosely modeled after the fair queueing algorithm: https://en.wikipedia.org/wiki/Fair_queuing.
*
- * @template Worker Type of worker which manages the strategy.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker which manages the strategy.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export class FairShareWorkerChoiceStrategy<
Worker extends IPoolWorker,
Data,
Response
> extends AbstractWorkerChoiceStrategy<Worker, Data, Response> {
- /** @inheritDoc */
+ /** {@inheritDoc} */
public readonly requiredStatistics: RequiredStatistics = {
runTime: true
}
WorkerVirtualTaskTimestamp
> = new Map<Worker, WorkerVirtualTaskTimestamp>()
- /** @inheritDoc */
+ /** {@inheritDoc} */
public reset (): boolean {
this.workerLastVirtualTaskTimestamp.clear()
return true
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public choose (): Worker {
let minWorkerVirtualTaskEndTimestamp = Infinity
let chosenWorker!: Worker
/**
* Computes worker last virtual task timestamp.
*
- * @param worker The worker.
+ * @param worker - The worker.
*/
private computeWorkerLastVirtualTaskTimestamp (worker: Worker): void {
const workerVirtualTaskStartTimestamp = Math.max(
/**
* Selects the less recently used worker.
*
- * @template Worker Type of worker which manages the strategy.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker which manages the strategy.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export class LessRecentlyUsedWorkerChoiceStrategy<
Worker extends IPoolWorker,
Data,
Response
> extends AbstractWorkerChoiceStrategy<Worker, Data, Response> {
- /** @inheritDoc */
+ /** {@inheritDoc} */
public reset (): boolean {
return true
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public choose (): Worker {
let minNumberOfRunningTasks = Infinity
// A worker is always found because it picks the one with fewer tasks
/**
* Selects the next worker in a round robin fashion.
*
- * @template Worker Type of worker which manages the strategy.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker which manages the strategy.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export class RoundRobinWorkerChoiceStrategy<
Worker extends IPoolWorker,
*/
private nextWorkerIndex: number = 0
- /** @inheritDoc */
+ /** {@inheritDoc} */
public reset (): boolean {
this.nextWorkerIndex = 0
return true
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public choose (): Worker {
const chosenWorker = this.pool.workers[this.nextWorkerIndex]
this.nextWorkerIndex =
/**
* Worker choice strategy interface.
*
- * @template Worker Type of worker which manages the strategy.
+ * @typeParam Worker - Type of worker which manages the strategy.
*/
export interface IWorkerChoiceStrategy<Worker extends IPoolWorker> {
/**
/**
* Gets the worker choice strategy instance.
*
- * @param pool The pool instance.
- * @param workerChoiceStrategy The worker choice strategy.
+ * @param pool - The pool instance.
+ * @param workerChoiceStrategy - The worker choice strategy.
* @returns The worker choice strategy instance.
*/
export function getWorkerChoiceStrategy<
* Selects the next worker with a weighted round robin scheduling algorithm.
* Loosely modeled after the weighted round robin queueing algorithm: https://en.wikipedia.org/wiki/Weighted_round_robin.
*
- * @template Worker Type of worker which manages the strategy.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker which manages the strategy.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export class WeightedRoundRobinWorkerChoiceStrategy<
Worker extends IPoolWorker,
Data,
Response
> extends AbstractWorkerChoiceStrategy<Worker, Data, Response> {
- /** @inheritDoc */
+ /** {@inheritDoc} */
public readonly requiredStatistics: RequiredStatistics = {
runTime: true
}
/**
* Constructs a worker choice strategy that selects with a weighted round robin scheduling algorithm.
*
- * @param pool The pool instance.
+ * @param pool - The pool instance.
*/
public constructor (pool: IPoolInternal<Worker, Data, Response>) {
super(pool)
this.initWorkersTaskRunTime()
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public reset (): boolean {
this.currentWorkerIndex = 0
this.workersTaskRunTime.clear()
return true
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public choose (): Worker {
const chosenWorker = this.pool.workers[this.currentWorkerIndex]
if (this.isDynamicPool && !this.workersTaskRunTime.has(chosenWorker)) {
/**
* The worker choice strategy context.
*
- * @template Worker Type of worker.
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export class WorkerChoiceStrategyContext<
Worker extends IPoolWorker,
/**
* Worker choice strategy context constructor.
*
- * @param pool The pool instance.
- * @param createDynamicallyWorkerCallback The worker creation callback for dynamic pool.
- * @param workerChoiceStrategy The worker choice strategy.
+ * @param pool - The pool instance.
+ * @param createDynamicallyWorkerCallback - The worker creation callback for dynamic pool.
+ * @param workerChoiceStrategy - The worker choice strategy.
*/
public constructor (
private readonly pool: IPoolInternal<Worker, Data, Response>,
/**
* Gets the worker choice strategy instance specific to the pool type.
*
- * @param workerChoiceStrategy The worker choice strategy.
+ * @param workerChoiceStrategy - The worker choice strategy.
* @returns The worker choice strategy instance for the pool type.
*/
private getPoolWorkerChoiceStrategy (
/**
* Sets the worker choice strategy to use in the context.
*
- * @param workerChoiceStrategy The worker choice strategy to set.
+ * @param workerChoiceStrategy - The worker choice strategy to set.
*/
public setWorkerChoiceStrategy (
workerChoiceStrategy: WorkerChoiceStrategy
* This thread pool creates new threads when the others are busy, up to the maximum number of threads.
* When the maximum number of threads is reached, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
*
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
* @since 0.0.1
*/
/**
* Constructs a new poolifier dynamic thread pool.
*
- * @param min Minimum number of threads which are always active.
- * @param max Maximum number of threads that can be created by this pool.
- * @param filePath Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.
- * @param opts Options for this dynamic thread pool.
+ * @param min - Minimum number of threads which are always active.
+ * @param max - Maximum number of threads that can be created by this pool.
+ * @param filePath - Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.
+ * @param opts - Options for this dynamic thread pool.
*/
public constructor (
min: number,
super(min, filePath, opts)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get type (): PoolType {
return PoolType.DYNAMIC
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get busy (): boolean {
return this.workers.length === this.max
}
*
* This pool selects the threads in a round robin fashion.
*
- * @template Data Type of data sent to the worker. This can only be serializable data.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
* @since 0.0.1
*/
/**
* Constructs a new poolifier fixed thread pool.
*
- * @param numberOfThreads Number of threads for this pool.
- * @param filePath Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.
- * @param opts Options for this fixed thread pool.
+ * @param numberOfThreads - Number of threads for this pool.
+ * @param filePath - Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.
+ * @param opts - Options for this fixed thread pool.
*/
public constructor (
numberOfThreads: number,
super(numberOfThreads, filePath, opts)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected isMain (): boolean {
return isMainThread
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public async destroyWorker (
worker: ThreadWorkerWithMessageChannel
): Promise<void> {
await worker.terminate()
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected sendToWorker (
worker: ThreadWorkerWithMessageChannel,
message: MessageValue<Data>
worker.postMessage(message)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public registerWorkerMessageListener<Message extends Data | Response>(
messageChannel: ThreadWorkerWithMessageChannel,
listener: (message: MessageValue<Message>) => void
messageChannel.port2?.on('message', listener)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected createWorker (): ThreadWorkerWithMessageChannel {
return new Worker(this.filePath, {
env: SHARE_ENV
})
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected afterWorkerSetup (worker: ThreadWorkerWithMessageChannel): void {
const { port1, port2 } = new MessageChannel()
worker.postMessage({ parent: port1 }, [port1])
this.registerWorkerMessageListener(worker, super.workerListener())
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get type (): PoolType {
return PoolType.FIXED
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
public get busy (): boolean {
return this.internalGetBusyStatus()
}
/**
* An object holding the worker that will be used to resolve/rejects the promise later on.
*
- * @template Worker Type of worker.
- * @template Response Type of response of execution. This can only be serializable data.
+ * @typeParam Worker - Type of worker.
+ * @typeParam Response - Type of response of execution. This can only be serializable data.
*/
export interface PromiseWorkerResponseWrapper<
Worker extends IPoolWorker,
/**
* Base class that implements some shared logic for all poolifier workers.
*
- * @template MainWorker Type of main worker.
- * @template Data Type of data this worker receives from pool's execution. This can only be serializable data.
- * @template Response Type of response the worker sends back to the main worker. This can only be serializable data.
+ * @typeParam MainWorker - Type of main worker.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
+ * @typeParam Response - Type of response the worker sends back to the main worker. This can only be serializable data.
*/
export abstract class AbstractWorker<
MainWorker extends Worker | MessagePort,
/**
* Constructs a new poolifier worker.
*
- * @param type The type of async event.
- * @param isMain Whether this is the main worker or not.
- * @param fn Function processed by the worker when the pool's `execution` function is invoked.
- * @param mainWorker Reference to main worker.
- * @param opts Options for the worker.
+ * @param type - The type of async event.
+ * @param isMain - Whether this is the main worker or not.
+ * @param fn - Function processed by the worker when the pool's `execution` function is invoked.
+ * @param mainWorker - Reference to main worker.
+ * @param opts - Options for the worker.
*/
public constructor (
type: string,
/**
* Checks if the `fn` parameter is passed to the constructor.
*
- * @param fn The function that should be defined.
+ * @param fn - The function that should be defined.
*/
private checkFunctionInput (fn: (data: Data) => Response): void {
if (fn == null) throw new Error('fn parameter is mandatory')
/**
* Sends a message to the main worker.
*
- * @param message The response message.
+ * @param message - The response message.
*/
protected abstract sendToMainWorker (message: MessageValue<Response>): void
/**
* Handles an error and convert it to a string so it can be sent back to the main worker.
*
- * @param e The error raised by the worker.
+ * @param e - The error raised by the worker.
* @returns Message of the error.
*/
protected handleError (e: Error | string): string {
/**
* Runs the given function synchronously.
*
- * @param fn Function that will be executed.
- * @param value Input data for the given function.
+ * @param fn - Function that will be executed.
+ * @param value - Input data for the given function.
*/
protected run (
fn: (data?: Data) => Response,
/**
* Runs the given function asynchronously.
*
- * @param fn Function that will be executed.
- * @param value Input data for the given function.
+ * @param fn - Function that will be executed.
+ * @param value - Input data for the given function.
*/
protected runAsync (
fn: (data?: Data) => Promise<Response>,
* If you use a `DynamicClusterPool` the extra workers that were created will be terminated,
* but the minimum number of workers will be guaranteed.
*
- * @template Data Type of data this worker receives from pool's execution. This can only be serializable data.
- * @template Response Type of response the worker sends back to the main worker. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
+ * @typeParam Response - Type of response the worker sends back to the main worker. This can only be serializable data.
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
* @since 2.0.0
*/
/**
* Constructs a new poolifier cluster worker.
*
- * @param fn Function processed by the worker when the pool's `execution` function is invoked.
- * @param opts Options for the worker.
+ * @param fn - Function processed by the worker when the pool's `execution` function is invoked.
+ * @param opts - Options for the worker.
*/
public constructor (fn: (data: Data) => Response, opts: WorkerOptions = {}) {
super(
)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected sendToMainWorker (message: MessageValue<Response>): void {
this.getMainWorker().send(message)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected handleError (e: Error | string): string {
return e instanceof Error ? e.message : e
}
* If you use a `DynamicThreadPool` the extra workers that were created will be terminated,
* but the minimum number of workers will be guaranteed.
*
- * @template Data Type of data this worker receives from pool's execution. This can only be serializable data.
- * @template Response Type of response the worker sends back to the main thread. This can only be serializable data.
+ * @typeParam Data - Type of data this worker receives from pool's execution. This can only be serializable data.
+ * @typeParam Response - Type of response the worker sends back to the main thread. This can only be serializable data.
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
* @since 0.0.1
*/
/**
* Constructs a new poolifier thread worker.
*
- * @param fn Function processed by the worker when the pool's `execution` function is invoked.
- * @param opts Options for the worker.
+ * @param fn - Function processed by the worker when the pool's `execution` function is invoked.
+ * @param opts - Options for the worker.
*/
public constructor (fn: (data: Data) => Response, opts: WorkerOptions = {}) {
super('worker-thread-pool:poolifier', isMainThread, fn, parentPort, opts)
}
- /** @inheritDoc */
+ /** {@inheritDoc} */
protected sendToMainWorker (message: MessageValue<Response>): void {
this.getMainWorker().postMessage(message)
}
/**
* 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.
- * @param value Any value.
+ * @typeParam KB - Which specific KillBehavior to test against.
+ * @param killBehavior - Which kind of kill behavior to detect.
+ * @param value - Any value.
* @returns `true` if `value` was strictly equals to `killBehavior`, otherwise `false`.
*/
export function isKillBehavior<KB extends KillBehavior> (
* 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 completed.
*
- * @default 60000 ms
+ * @defaultValue 60000 ms
*/
maxInactiveTime?: number
/**
* Whether your worker will perform asynchronous or not.
*
- * @default false
+ * @defaultValue false
*/
async?: boolean
/**
*
* This option only apply to the newly created workers.
*
- * @default KillBehaviors.SOFT
+ * @defaultValue KillBehaviors.SOFT
*/
killBehavior?: KillBehavior
}