From 9efbac5b97d10f6fd0d8a64f1130c40bdebc7c44 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Mon, 17 May 2021 22:13:17 +0200 Subject: [PATCH] Add configuration tunable for pool worker choice strategy MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- README.md | 1 + src/charging-station/Bootstrap.ts | 5 ++++- src/types/ConfigurationData.ts | 2 ++ src/types/Worker.ts | 2 ++ src/utils/Configuration.ts | 5 +++++ src/worker/WorkerDynamicPool.ts | 20 +++++++++----------- src/worker/WorkerFactory.ts | 4 ++-- src/worker/WorkerStaticPool.ts | 20 +++++++++----------- 8 files changed, 34 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 9b5d68be..e377862a 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ workerProcess | workerSet/staticPool/dynamicPool | workerSet | string | worker t workerStartDelay | | 500 | integer | milliseconds to wait at charging station worker threads startup workerPoolMinSize | | 4 | integer | worker threads pool minimum number of threads workerPoolMaxSize | | 16 | integer | worker threads pool maximum number of threads +workerPoolStrategy | ROUND_ROBIN/LESS_RECENTLY_USED/... | [poolifier](https://github.com/pioardi/poolifier) default: ROUND_ROBBIN | string | worker threads pool [poolifier](https://github.com/pioardi/poolifier) worker choice strategy chargingStationsPerWorker | | 1 | integer | number of charging stations per worker threads for the `workerSet` process type logConsole | true/false | false | boolean | output logs on the console logFormat | | simple | string | winston log format diff --git a/src/charging-station/Bootstrap.ts b/src/charging-station/Bootstrap.ts index bb101ca7..d6ebd549 100644 --- a/src/charging-station/Bootstrap.ts +++ b/src/charging-station/Bootstrap.ts @@ -83,7 +83,10 @@ export default class Bootstrap { startDelay: Configuration.getWorkerStartDelay(), poolMaxSize: Configuration.getWorkerPoolMaxSize(), poolMinSize: Configuration.getWorkerPoolMinSize(), - elementsPerWorker: Configuration.getChargingStationsPerWorker() + elementsPerWorker: Configuration.getChargingStationsPerWorker(), + poolOptions: { + workerChoiceStrategy: Configuration.getWorkerPoolStrategy() + } }); } return this.workerImplementationInstance; diff --git a/src/types/ConfigurationData.ts b/src/types/ConfigurationData.ts index 9c7c098e..6d67a06e 100644 --- a/src/types/ConfigurationData.ts +++ b/src/types/ConfigurationData.ts @@ -1,3 +1,4 @@ +import type { WorkerChoiceStrategy } from 'poolifier'; import { WorkerProcessType } from './Worker'; export interface StationTemplateURL { @@ -16,6 +17,7 @@ export default interface ConfigurationData { workerStartDelay?: number; workerPoolMinSize?: number; workerPoolMaxSize?: number; + workerPoolStrategy?: WorkerChoiceStrategy; chargingStationsPerWorker?: number; logFormat?: string; logLevel?: string; diff --git a/src/types/Worker.ts b/src/types/Worker.ts index dde976ae..c1f6f0c8 100644 --- a/src/types/Worker.ts +++ b/src/types/Worker.ts @@ -1,3 +1,4 @@ +import { PoolOptions } from 'poolifier'; import { Worker } from 'worker_threads'; export enum WorkerProcessType { @@ -11,6 +12,7 @@ export interface WorkerOptions { poolMaxSize?: number; poolMinSize?: number; elementsPerWorker?: number; + poolOptions?: PoolOptions; } // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/src/utils/Configuration.ts b/src/utils/Configuration.ts index 4bc1853d..1a2b714a 100644 --- a/src/utils/Configuration.ts +++ b/src/utils/Configuration.ts @@ -1,6 +1,7 @@ import ConfigurationData, { StationTemplateURL } from '../types/ConfigurationData'; import Constants from './Constants'; +import type { WorkerChoiceStrategy } from 'poolifier'; import { WorkerProcessType } from '../types/Worker'; import fs from 'fs'; import path from 'path'; @@ -65,6 +66,10 @@ export default class Configuration { return Configuration.objectHasOwnProperty(Configuration.getConfig(), 'workerPoolMaxSize') ? Configuration.getConfig().workerPoolMaxSize : 16; } + static getWorkerPoolStrategy(): WorkerChoiceStrategy { + return Configuration.getConfig().workerPoolStrategy; + } + static getChargingStationsPerWorker(): number { return Configuration.objectHasOwnProperty(Configuration.getConfig(), 'chargingStationsPerWorker') ? Configuration.getConfig().chargingStationsPerWorker : 1; } diff --git a/src/worker/WorkerDynamicPool.ts b/src/worker/WorkerDynamicPool.ts index cf22c0a8..a8f68978 100644 --- a/src/worker/WorkerDynamicPool.ts +++ b/src/worker/WorkerDynamicPool.ts @@ -15,10 +15,11 @@ export default class WorkerDynamicPool extends WorkerAbstract { * @param {number} min * @param {number} max * @param {number} workerStartDelay + * @param {PoolOptions} opts */ - constructor(workerScript: string, min: number, max: number, workerStartDelay?: number) { + constructor(workerScript: string, min: number, max: number, workerStartDelay?: number, opts?: PoolOptions) { super(workerScript, workerStartDelay); - this.pool = DynamicPool.getInstance(min, max, this.workerScript); + this.pool = DynamicPool.getInstance(min, max, this.workerScript, opts); } get size(): number { @@ -67,17 +68,14 @@ class DynamicPool extends DynamicThreadPool { super(min, max, workerScript, opts); } - public static getInstance(min: number, max: number, workerScript: string): DynamicPool { + public static getInstance(min: number, max: number, workerScript: string, opts?: PoolOptions): DynamicPool { if (!DynamicPool.instance) { - DynamicPool.instance = new DynamicPool(min, max, workerScript, - { - exitHandler: (code) => { - if (code !== 0) { - console.error(`Worker stopped with exit code ${code}`); - } - } + opts.exitHandler = opts.exitHandler ?? ((code) => { + if (code !== 0) { + console.error(`Worker stopped with exit code ${code}`); } - ); + }); + DynamicPool.instance = new DynamicPool(min, max, workerScript, opts); } return DynamicPool.instance; } diff --git a/src/worker/WorkerFactory.ts b/src/worker/WorkerFactory.ts index 34369e18..2cda0ca2 100644 --- a/src/worker/WorkerFactory.ts +++ b/src/worker/WorkerFactory.ts @@ -20,11 +20,11 @@ export default class WorkerFactory { return new WorkerSet(workerScript, options.elementsPerWorker, options.startDelay); case WorkerProcessType.STATIC_POOL: options.poolMaxSize = options.poolMaxSize ?? 16; - return new WorkerStaticPool(workerScript, options.poolMaxSize, options.startDelay); + return new WorkerStaticPool(workerScript, options.poolMaxSize, options.startDelay, options.poolOptions); case WorkerProcessType.DYNAMIC_POOL: options.poolMinSize = options.poolMinSize ?? 4; options.poolMaxSize = options.poolMaxSize ?? 16; - return new WorkerDynamicPool(workerScript, options.poolMinSize, options.poolMaxSize, options.startDelay); + return new WorkerDynamicPool(workerScript, options.poolMinSize, options.poolMaxSize, options.startDelay, options.poolOptions); default: return null; } diff --git a/src/worker/WorkerStaticPool.ts b/src/worker/WorkerStaticPool.ts index c78768e0..076b1ee0 100644 --- a/src/worker/WorkerStaticPool.ts +++ b/src/worker/WorkerStaticPool.ts @@ -14,10 +14,11 @@ export default class WorkerStaticPool extends WorkerAbstract { * @param {string} workerScript * @param {number} numberOfThreads * @param {number} startWorkerDelay + * @param {PoolOptions} opts */ - constructor(workerScript: string, numberOfThreads: number, startWorkerDelay?: number) { + constructor(workerScript: string, numberOfThreads: number, startWorkerDelay?: number, opts?: PoolOptions) { super(workerScript, startWorkerDelay); - this.pool = StaticPool.getInstance(numberOfThreads, this.workerScript); + this.pool = StaticPool.getInstance(numberOfThreads, this.workerScript, opts); } get size(): number { @@ -65,17 +66,14 @@ class StaticPool extends FixedThreadPool { super(numberOfThreads, workerScript, opts); } - public static getInstance(numberOfThreads: number, workerScript: string): StaticPool { + public static getInstance(numberOfThreads: number, workerScript: string, opts?: PoolOptions): StaticPool { if (!StaticPool.instance) { - StaticPool.instance = new StaticPool(numberOfThreads, workerScript, - { - exitHandler: (code) => { - if (code !== 0) { - console.error(`Worker stopped with exit code ${code}`); - } - } + opts.exitHandler = opts.exitHandler ?? ((code) => { + if (code !== 0) { + console.error(`Worker stopped with exit code ${code}`); } - ); + }); + StaticPool.instance = new StaticPool(numberOfThreads, workerScript, opts); } return StaticPool.instance; } -- 2.34.1