X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Futils.ts;h=b38cf948e833ef41ccc7d183db0498a8e4257ed0;hb=efc4d37dd21d0c80e5fa2d58009e6298eefe5d48;hp=20493767db87d80689a6cb067df3e22f72b759ce;hpb=00e1bdeb5c50b0eede8fe2f72d47bf8992e4aede;p=poolifier.git diff --git a/src/utils.ts b/src/utils.ts index 20493767..b38cf948 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,14 +1,15 @@ import * as os from 'node:os' -import { getRandomValues } from 'node:crypto' +import { getRandomValues, randomInt } from 'node:crypto' import { Worker as ClusterWorker } from 'node:cluster' import { Worker as ThreadWorker } from 'node:worker_threads' import { cpus } from 'node:os' import type { - InternalWorkerChoiceStrategyOptions, - MeasurementStatisticsRequirements -} from './pools/selection-strategies/selection-strategies-types' -import type { KillBehavior } from './worker/worker-options' -import { type IWorker, type WorkerType, WorkerTypes } from './pools/worker' + MeasurementStatisticsRequirements, + WorkerChoiceStrategyOptions +} from './pools/selection-strategies/selection-strategies-types.js' +import type { KillBehavior } from './worker/worker-options.js' +import { type IWorker, type WorkerType, WorkerTypes } from './pools/worker.js' +import type { IPool } from './pools/pool.js' /** * Default task name. @@ -22,23 +23,6 @@ export const EMPTY_FUNCTION: () => void = Object.freeze(() => { /* Intentionally empty */ }) -/** - * Gets default worker choice strategy options. - * - * @param retries - The number of worker choice retries. - * @returns The default worker choice strategy options. - */ -const getDefaultInternalWorkerChoiceStrategyOptions = ( - retries: number -): InternalWorkerChoiceStrategyOptions => { - return { - retries, - runTime: { median: false }, - waitTime: { median: false }, - elu: { median: false } - } -} - /** * Default measurement statistics requirements. */ @@ -194,7 +178,7 @@ export const round = (num: number, scale = 2): number => { export const isPlainObject = (obj: unknown): boolean => typeof obj === 'object' && obj !== null && - obj?.constructor === Object && + obj.constructor === Object && Object.prototype.toString.call(obj) === '[object Object]' /** @@ -273,6 +257,7 @@ export const once = ( ): ((...args: A) => R) => { let result: R return (...args: A) => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (fn != null) { result = fn.apply(context, args) ;(fn as unknown as undefined) = (context as unknown as undefined) = @@ -282,30 +267,49 @@ export const once = ( } } -const clone = (object: T): T => { - return JSON.parse(JSON.stringify(object)) as T +export const getWorkerChoiceStrategyRetries = < + Worker extends IWorker, + Data, + Response +>( + pool: IPool, + opts?: WorkerChoiceStrategyOptions + ): number => { + return ( + pool.info.maxSize + + Object.keys(opts?.weights ?? getDefaultWeights(pool.info.maxSize)).length + ) } -export const buildInternalWorkerChoiceStrategyOptions = ( - poolMaxSize: number, - opts?: InternalWorkerChoiceStrategyOptions -): InternalWorkerChoiceStrategyOptions => { +const clone = (object: T): T => { + return structuredClone(object) +} + +export const buildWorkerChoiceStrategyOptions = < + Worker extends IWorker, + Data, + Response +>( + pool: IPool, + opts?: WorkerChoiceStrategyOptions + ): WorkerChoiceStrategyOptions => { opts = clone(opts ?? {}) - if (opts.weights == null) { - opts.weights = getDefaultWeights(poolMaxSize) - } + opts.weights = opts.weights ?? getDefaultWeights(pool.info.maxSize) return { - ...getDefaultInternalWorkerChoiceStrategyOptions( - poolMaxSize + Object.keys(opts?.weights ?? {}).length - ), + ...{ + runTime: { median: false }, + waitTime: { median: false }, + elu: { median: false } + }, ...opts } } const getDefaultWeights = ( poolMaxSize: number, - defaultWorkerWeight: number = getDefaultWorkerWeight() + defaultWorkerWeight?: number ): Record => { + defaultWorkerWeight = defaultWorkerWeight ?? getDefaultWorkerWeight() const weights: Record = {} for (let workerNodeKey = 0; workerNodeKey < poolMaxSize; workerNodeKey++) { weights[workerNodeKey] = defaultWorkerWeight @@ -314,8 +318,16 @@ const getDefaultWeights = ( } const getDefaultWorkerWeight = (): number => { + const cpuSpeed = randomInt(500, 2500) let cpusCycleTimeWeight = 0 for (const cpu of cpus()) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (cpu.speed == null || cpu.speed === 0) { + cpu.speed = + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + cpus().find(cpu => cpu.speed != null && cpu.speed !== 0)?.speed ?? + cpuSpeed + } // CPU estimated cycle time const numberOfDigits = cpu.speed.toString().length - 1 const cpuCycleTime = 1 / (cpu.speed / Math.pow(10, numberOfDigits))