From: Jérôme Benoit Date: Tue, 19 Sep 2023 20:18:58 +0000 (+0200) Subject: refactor: factor out pool helpers X-Git-Tag: v2.7.1~16 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;ds=sidebyside;h=bde6b5d701d895c3e1b447f48750d42a7ac66603;p=poolifier.git refactor: factor out pool helpers Signed-off-by: Jérôme Benoit --- diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index 9aeeebed..ce59c992 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -1,6 +1,5 @@ import { randomUUID } from 'node:crypto' import { performance } from 'node:perf_hooks' -import { existsSync } from 'node:fs' import { type TransferListItem } from 'node:worker_threads' import type { MessageValue, @@ -49,6 +48,11 @@ import { import { WorkerChoiceStrategyContext } from './selection-strategies/worker-choice-strategy-context' import { version } from './version' import { WorkerNode } from './worker-node' +import { + checkFilePath, + checkValidTasksQueueOptions, + checkValidWorkerChoiceStrategy +} from './utils' /** * Base class that implements some shared logic for all poolifier pools. @@ -130,7 +134,7 @@ export abstract class AbstractPool< ) } this.checkNumberOfWorkers(this.numberOfWorkers) - this.checkFilePath(this.filePath) + checkFilePath(this.filePath) this.checkPoolOptions(this.opts) this.chooseWorkerNode = this.chooseWorkerNode.bind(this) @@ -163,19 +167,6 @@ export abstract class AbstractPool< this.startTimestamp = performance.now() } - private checkFilePath (filePath: string): void { - if ( - filePath == null || - typeof filePath !== 'string' || - (typeof filePath === 'string' && filePath.trim().length === 0) - ) { - throw new Error('Please specify a file with a worker implementation') - } - if (!existsSync(filePath)) { - throw new Error(`Cannot find the worker file '${filePath}'`) - } - } - private checkNumberOfWorkers (numberOfWorkers: number): void { if (numberOfWorkers == null) { throw new Error( @@ -194,36 +185,10 @@ export abstract class AbstractPool< } } - protected checkDynamicPoolSize (min: number, max: number): void { - if (this.type === PoolTypes.dynamic) { - if (max == null) { - throw new TypeError( - 'Cannot instantiate a dynamic pool without specifying the maximum pool size' - ) - } else if (!Number.isSafeInteger(max)) { - throw new TypeError( - 'Cannot instantiate a dynamic pool with a non safe integer maximum pool size' - ) - } else if (min > max) { - throw new RangeError( - 'Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size' - ) - } else if (max === 0) { - throw new RangeError( - 'Cannot instantiate a dynamic pool with a maximum pool size equal to zero' - ) - } else if (min === max) { - throw new RangeError( - 'Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead' - ) - } - } - } - private checkPoolOptions (opts: PoolOptions): void { if (isPlainObject(opts)) { this.opts.startWorkers = opts.startWorkers ?? true - this.checkValidWorkerChoiceStrategy( + checkValidWorkerChoiceStrategy( opts.workerChoiceStrategy as WorkerChoiceStrategy ) this.opts.workerChoiceStrategy = @@ -239,9 +204,7 @@ export abstract class AbstractPool< this.opts.enableEvents = opts.enableEvents ?? true this.opts.enableTasksQueue = opts.enableTasksQueue ?? false if (this.opts.enableTasksQueue) { - this.checkValidTasksQueueOptions( - opts.tasksQueueOptions as TasksQueueOptions - ) + checkValidTasksQueueOptions(opts.tasksQueueOptions as TasksQueueOptions) this.opts.tasksQueueOptions = this.buildTasksQueueOptions( opts.tasksQueueOptions as TasksQueueOptions ) @@ -251,19 +214,6 @@ export abstract class AbstractPool< } } - private checkValidWorkerChoiceStrategy ( - workerChoiceStrategy: WorkerChoiceStrategy - ): void { - if ( - workerChoiceStrategy != null && - !Object.values(WorkerChoiceStrategies).includes(workerChoiceStrategy) - ) { - throw new Error( - `Invalid worker choice strategy '${workerChoiceStrategy}'` - ) - } - } - private checkValidWorkerChoiceStrategyOptions ( workerChoiceStrategyOptions: WorkerChoiceStrategyOptions ): void { @@ -311,43 +261,6 @@ export abstract class AbstractPool< } } - private checkValidTasksQueueOptions ( - tasksQueueOptions: TasksQueueOptions - ): void { - if (tasksQueueOptions != null && !isPlainObject(tasksQueueOptions)) { - throw new TypeError('Invalid tasks queue options: must be a plain object') - } - if ( - tasksQueueOptions?.concurrency != null && - !Number.isSafeInteger(tasksQueueOptions.concurrency) - ) { - throw new TypeError( - 'Invalid worker node tasks concurrency: must be an integer' - ) - } - if ( - tasksQueueOptions?.concurrency != null && - tasksQueueOptions.concurrency <= 0 - ) { - throw new RangeError( - `Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency} is a negative integer or zero` - ) - } - if ( - tasksQueueOptions?.size != null && - !Number.isSafeInteger(tasksQueueOptions.size) - ) { - throw new TypeError( - 'Invalid worker node tasks queue size: must be an integer' - ) - } - if (tasksQueueOptions?.size != null && tasksQueueOptions.size <= 0) { - throw new RangeError( - `Invalid worker node tasks queue size: ${tasksQueueOptions.size} is a negative integer or zero` - ) - } - } - /** @inheritDoc */ public get info (): PoolInfo { return { @@ -614,7 +527,7 @@ export abstract class AbstractPool< workerChoiceStrategy: WorkerChoiceStrategy, workerChoiceStrategyOptions?: WorkerChoiceStrategyOptions ): void { - this.checkValidWorkerChoiceStrategy(workerChoiceStrategy) + checkValidWorkerChoiceStrategy(workerChoiceStrategy) this.opts.workerChoiceStrategy = workerChoiceStrategy this.workerChoiceStrategyContext.setWorkerChoiceStrategy( this.opts.workerChoiceStrategy @@ -659,7 +572,7 @@ export abstract class AbstractPool< /** @inheritDoc */ public setTasksQueueOptions (tasksQueueOptions: TasksQueueOptions): void { if (this.opts.enableTasksQueue === true) { - this.checkValidTasksQueueOptions(tasksQueueOptions) + checkValidTasksQueueOptions(tasksQueueOptions) this.opts.tasksQueueOptions = this.buildTasksQueueOptions(tasksQueueOptions) this.setTasksQueueSize(this.opts.tasksQueueOptions.size as number) diff --git a/src/pools/cluster/dynamic.ts b/src/pools/cluster/dynamic.ts index b93d7e87..99a89966 100644 --- a/src/pools/cluster/dynamic.ts +++ b/src/pools/cluster/dynamic.ts @@ -1,4 +1,5 @@ import { type PoolType, PoolTypes } from '../pool' +import { checkDynamicPoolSize } from '../utils' import { type ClusterPoolOptions, FixedClusterPool } from './fixed' /** @@ -31,7 +32,7 @@ export class DynamicClusterPool< opts: ClusterPoolOptions = {} ) { super(min, filePath, opts) - this.checkDynamicPoolSize(this.numberOfWorkers, this.max) + checkDynamicPoolSize(this.numberOfWorkers, this.max) } /** @inheritDoc */ diff --git a/src/pools/thread/dynamic.ts b/src/pools/thread/dynamic.ts index a34f0c25..119e556d 100644 --- a/src/pools/thread/dynamic.ts +++ b/src/pools/thread/dynamic.ts @@ -1,4 +1,5 @@ import { type PoolType, PoolTypes } from '../pool' +import { checkDynamicPoolSize } from '../utils' import { FixedThreadPool, type ThreadPoolOptions } from './fixed' /** @@ -31,7 +32,7 @@ export class DynamicThreadPool< opts: ThreadPoolOptions = {} ) { super(min, filePath, opts) - this.checkDynamicPoolSize(this.numberOfWorkers, this.max) + checkDynamicPoolSize(this.numberOfWorkers, this.max) } /** @inheritDoc */ diff --git a/src/pools/utils.ts b/src/pools/utils.ts new file mode 100644 index 00000000..4aac5cda --- /dev/null +++ b/src/pools/utils.ts @@ -0,0 +1,92 @@ +import { existsSync } from 'node:fs' +import { isPlainObject } from '../utils' +import { + WorkerChoiceStrategies, + type WorkerChoiceStrategy +} from './selection-strategies/selection-strategies-types' +import type { TasksQueueOptions } from './pool' + +export const checkFilePath = (filePath: string): void => { + if ( + filePath == null || + typeof filePath !== 'string' || + (typeof filePath === 'string' && filePath.trim().length === 0) + ) { + throw new Error('Please specify a file with a worker implementation') + } + if (!existsSync(filePath)) { + throw new Error(`Cannot find the worker file '${filePath}'`) + } +} + +export const checkDynamicPoolSize = (min: number, max: number): void => { + if (max == null) { + throw new TypeError( + 'Cannot instantiate a dynamic pool without specifying the maximum pool size' + ) + } else if (!Number.isSafeInteger(max)) { + throw new TypeError( + 'Cannot instantiate a dynamic pool with a non safe integer maximum pool size' + ) + } else if (min > max) { + throw new RangeError( + 'Cannot instantiate a dynamic pool with a maximum pool size inferior to the minimum pool size' + ) + } else if (max === 0) { + throw new RangeError( + 'Cannot instantiate a dynamic pool with a maximum pool size equal to zero' + ) + } else if (min === max) { + throw new RangeError( + 'Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead' + ) + } +} + +export const checkValidWorkerChoiceStrategy = ( + workerChoiceStrategy: WorkerChoiceStrategy +): void => { + if ( + workerChoiceStrategy != null && + !Object.values(WorkerChoiceStrategies).includes(workerChoiceStrategy) + ) { + throw new Error(`Invalid worker choice strategy '${workerChoiceStrategy}'`) + } +} + +export const checkValidTasksQueueOptions = ( + tasksQueueOptions: TasksQueueOptions +): void => { + if (tasksQueueOptions != null && !isPlainObject(tasksQueueOptions)) { + throw new TypeError('Invalid tasks queue options: must be a plain object') + } + if ( + tasksQueueOptions?.concurrency != null && + !Number.isSafeInteger(tasksQueueOptions.concurrency) + ) { + throw new TypeError( + 'Invalid worker node tasks concurrency: must be an integer' + ) + } + if ( + tasksQueueOptions?.concurrency != null && + tasksQueueOptions.concurrency <= 0 + ) { + throw new RangeError( + `Invalid worker node tasks concurrency: ${tasksQueueOptions.concurrency} is a negative integer or zero` + ) + } + if ( + tasksQueueOptions?.size != null && + !Number.isSafeInteger(tasksQueueOptions.size) + ) { + throw new TypeError( + 'Invalid worker node tasks queue size: must be an integer' + ) + } + if (tasksQueueOptions?.size != null && tasksQueueOptions.size <= 0) { + throw new RangeError( + `Invalid worker node tasks queue size: ${tasksQueueOptions.size} is a negative integer or zero` + ) + } +}