X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fpools%2Fselection-strategies.ts;h=f1c20befd6b709784f08f5fe339709d2bf3b1e3d;hb=e00a6c53e0d42d4b76791441975b70888ead0a73;hp=f86442b0f5fc836fd9cacf77333d1bab69f1fae2;hpb=ff5e76e152be8540cba8118bb4e2b9da314dfff5;p=poolifier.git diff --git a/src/pools/selection-strategies.ts b/src/pools/selection-strategies.ts index f86442b0..f1c20bef 100644 --- a/src/pools/selection-strategies.ts +++ b/src/pools/selection-strategies.ts @@ -1,6 +1,6 @@ -import { isKillBehavior, KillBehaviors } from '../worker/worker-options' import type { IWorker } from './abstract-pool' import type { IPoolInternal } from './pool-internal' +import { PoolType } from './pool-internal' /** * Enumeration of worker choice strategies. @@ -60,7 +60,7 @@ class RoundRobinWorkerChoiceStrategy public choose (): Worker { const chosenWorker = this.pool.workers[this.nextWorkerIndex] this.nextWorkerIndex = - this.pool.workers.length - 1 === this.nextWorkerIndex + this.nextWorkerIndex === this.pool.workers.length - 1 ? 0 : this.nextWorkerIndex + 1 return chosenWorker @@ -90,7 +90,7 @@ class LessRecentlyUsedWorkerChoiceStrategy< /** @inheritdoc */ public choose (): Worker { - const isPoolDynamic = this.pool.dynamic + const isPoolDynamic = this.pool.type === PoolType.DYNAMIC let minNumberOfTasks = Infinity // A worker is always found because it picks the one with fewer tasks let lessRecentlyUsedWorker!: Worker @@ -98,8 +98,8 @@ class LessRecentlyUsedWorkerChoiceStrategy< if (!isPoolDynamic && numberOfTasks === 0) { return worker } else if (numberOfTasks < minNumberOfTasks) { - minNumberOfTasks = numberOfTasks lessRecentlyUsedWorker = worker + minNumberOfTasks = numberOfTasks } } return lessRecentlyUsedWorker @@ -121,10 +121,12 @@ class DynamicPoolWorkerChoiceStrategy * Constructs a worker choice strategy for dynamical pools. * * @param pool The pool instance. - * @param workerChoiceStrategy The worker choice strategy when the pull is full. + * @param createDynamicallyWorkerCallback The worker creation callback for dynamic pool. + * @param workerChoiceStrategy The worker choice strategy when the pull is busy. */ public constructor ( private readonly pool: IPoolInternal, + private createDynamicallyWorkerCallback: () => Worker, workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN ) { this.workerChoiceStrategy = SelectionStrategiesUtils.getWorkerChoiceStrategy( @@ -135,31 +137,17 @@ class DynamicPoolWorkerChoiceStrategy /** @inheritdoc */ public choose (): Worker { - const freeWorker = SelectionStrategiesUtils.findFreeWorkerBasedOnTasks( - this.pool - ) - if (freeWorker) { - return freeWorker + const freeTaskMapEntry = this.pool.findFreeTasksMapEntry() + if (freeTaskMapEntry) { + return freeTaskMapEntry[0] } - if (this.pool.workers.length === this.pool.max) { - this.pool.emitter.emit('FullPool') + if (this.pool.busy) { return this.workerChoiceStrategy.choose() } // All workers are busy, create a new worker - const workerCreated = this.pool.createAndSetupWorker() - this.pool.registerWorkerMessageListener(workerCreated, message => { - const tasksInProgress = this.pool.tasks.get(workerCreated) - 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) - void this.pool.destroyWorker(workerCreated) - } - }) - return workerCreated + return this.createDynamicallyWorkerCallback() } } @@ -182,10 +170,12 @@ export class WorkerChoiceStrategyContext< * 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. */ public constructor ( private readonly pool: IPoolInternal, + private createDynamicallyWorkerCallback: () => Worker, workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN ) { this.setWorkerChoiceStrategy(workerChoiceStrategy) @@ -200,9 +190,10 @@ export class WorkerChoiceStrategyContext< private getPoolWorkerChoiceStrategy ( workerChoiceStrategy: WorkerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN ): IWorkerChoiceStrategy { - if (this.pool.dynamic) { + if (this.pool.type === PoolType.DYNAMIC) { return new DynamicPoolWorkerChoiceStrategy( this.pool, + this.createDynamicallyWorkerCallback, workerChoiceStrategy ) } @@ -236,33 +227,9 @@ export class WorkerChoiceStrategyContext< } /** - * Worker selection strategies helpers. + * Worker selection strategies helpers class. */ class SelectionStrategiesUtils { - /** - * Find a free worker based on number of tasks the worker has applied. - * - * If a worker was found that has `0` tasks, it is detected as free and will be returned. - * - * If no free worker was found, `null` will be returned. - * - * @param pool The pool instance. - * @returns A free worker if there was one, otherwise `null`. - */ - public static findFreeWorkerBasedOnTasks< - Worker extends IWorker, - Data, - Response - > (pool: IPoolInternal): Worker | null { - for (const [worker, numberOfTasks] of pool.tasks) { - if (numberOfTasks === 0) { - // A worker is free, use it - return worker - } - } - return null - } - /** * Get the worker choice strategy instance. * @@ -285,6 +252,7 @@ class SelectionStrategiesUtils { return new LessRecentlyUsedWorkerChoiceStrategy(pool) default: throw new Error( + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Worker choice strategy '${workerChoiceStrategy}' not found` ) }