-export const getWorkerChoiceStrategyRetries = <
- Worker extends IWorker,
- Data,
- Response
->(
- pool: IPool<Worker, Data, Response>,
- opts?: WorkerChoiceStrategyOptions
- ): number => {
- return (
- pool.info.maxSize +
- Object.keys(opts?.weights ?? getDefaultWeights(pool.info.maxSize)).length
- )
-}
-
-export const buildWorkerChoiceStrategyOptions = <
- Worker extends IWorker,
- Data,
- Response
->(
- pool: IPool<Worker, Data, Response>,
- opts?: WorkerChoiceStrategyOptions
- ): WorkerChoiceStrategyOptions => {
- opts = clone(opts ?? {})
- opts.weights = opts.weights ?? getDefaultWeights(pool.info.maxSize)
- return {
- ...{
- runTime: { median: false },
- waitTime: { median: false },
- elu: { median: false }
- },
- ...opts
- }
-}
-
-const clone = <T>(object: T): T => {
- return structuredClone<T>(object)
-}
-
-const getDefaultWeights = (
- poolMaxSize: number,
- defaultWorkerWeight?: number
-): Record<number, number> => {
- defaultWorkerWeight = defaultWorkerWeight ?? getDefaultWorkerWeight()
- const weights: Record<number, number> = {}
- for (let workerNodeKey = 0; workerNodeKey < poolMaxSize; workerNodeKey++) {
- weights[workerNodeKey] = defaultWorkerWeight
- }
- return weights
-}
-
-const estimatedCpuSpeed = (): number => {
- const runs = 150000000
- const begin = performance.now()
- // eslint-disable-next-line no-empty
- for (let i = runs; i > 0; i--) {}
- const end = performance.now()
- const duration = end - begin
- return Math.trunc(runs / duration / 1000) // in MHz
-}
-
-const getDefaultWorkerWeight = (): number => {
- const currentCpus = cpus()
- let estCpuSpeed: number | undefined
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- if (currentCpus.every(cpu => cpu.speed == null || cpu.speed === 0)) {
- estCpuSpeed = estimatedCpuSpeed()
- }
- let cpusCycleTimeWeight = 0
- for (const cpu of currentCpus) {
- // 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
- currentCpus.find(cpu => cpu.speed != null && cpu.speed !== 0)?.speed ??
- estCpuSpeed ??
- 2000
- }
- // 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 / currentCpus.length)
-}
-