X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Futils.ts;h=8e84e9474c8a91d1adceb740e5c5ff21292faa02;hb=35e8f29cac8e1c1fecb8a3404107602d2d482f19;hp=25233a022aac69f9db858907261ad6720e5e495e;hpb=26ce26ca8861318068427cc86697103e7a3ddbf4;p=poolifier.git diff --git a/src/utils.ts b/src/utils.ts index 25233a02..8e84e947 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,6 +2,7 @@ import * as os from 'node:os' import { getRandomValues } 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 @@ -22,16 +23,16 @@ export const EMPTY_FUNCTION: () => void = Object.freeze(() => { }) /** - * Default worker choice strategy options. + * Gets default worker choice strategy options. * - * @param poolMaxSize - The pool maximum size. + * @param retries - The number of worker choice retries. * @returns The default worker choice strategy options. */ -export const getDefaultInternalWorkerChoiceStrategyOptions = ( - poolMaxSize: number +const getDefaultInternalWorkerChoiceStrategyOptions = ( + retries: number ): InternalWorkerChoiceStrategyOptions => { return { - retries: poolMaxSize, + retries, runTime: { median: false }, waitTime: { median: false }, elu: { median: false } @@ -280,3 +281,45 @@ export const once = ( return result } } + +const clone = (object: T): T => { + return JSON.parse(JSON.stringify(object)) as T +} + +export const buildInternalWorkerChoiceStrategyOptions = ( + poolMaxSize: number, + opts?: InternalWorkerChoiceStrategyOptions +): InternalWorkerChoiceStrategyOptions => { + opts = clone(opts ?? {}) + if (opts?.weights == null) { + opts.weights = getDefaultWeights(poolMaxSize) + } + return { + ...getDefaultInternalWorkerChoiceStrategyOptions( + poolMaxSize + Object.keys(opts.weights).length + ), + ...opts + } +} + +const getDefaultWeights = ( + poolMaxSize: number, + defaultWorkerWeight: number = getDefaultWorkerWeight() +): Record => { + const weights: Record = {} + for (let workerNodeKey = 0; workerNodeKey < poolMaxSize; workerNodeKey++) { + weights[workerNodeKey] = defaultWorkerWeight + } + return weights +} + +const getDefaultWorkerWeight = (): number => { + let cpusCycleTimeWeight = 0 + for (const cpu of cpus()) { + // CPU estimated cycle time + const numberOfDigits = cpu.speed.toString().length - 1 + const cpuCycleTime = 1 / (cpu.speed / Math.pow(10, numberOfDigits)) + cpusCycleTimeWeight += cpuCycleTime * Math.pow(10, numberOfDigits) + } + return Math.round(cpusCycleTimeWeight / cpus().length) +}