refactor: code cleanups
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Tue, 21 May 2024 18:20:43 +0000 (20:20 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Tue, 21 May 2024 18:20:43 +0000 (20:20 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
23 files changed:
benchmarks/worker-selection/least.mjs
examples/typescript/http-client-pool/src/types.ts
examples/typescript/http-server-pool/express-cluster/src/worker.ts
examples/typescript/http-server-pool/express-hybrid/src/express-worker.ts
examples/typescript/http-server-pool/express-hybrid/src/request-handler-worker.ts
examples/typescript/http-server-pool/express-worker_threads/src/main.ts
examples/typescript/http-server-pool/express-worker_threads/src/pool.ts
examples/typescript/http-server-pool/express-worker_threads/src/worker.ts
examples/typescript/http-server-pool/fastify-hybrid/@types/fastify/index.d.ts
examples/typescript/http-server-pool/fastify-hybrid/src/fastify-poolifier.ts
examples/typescript/http-server-pool/fastify-hybrid/src/request-handler-worker.ts
examples/typescript/http-server-pool/fastify-worker_threads/src/fastify-poolifier.ts
examples/typescript/http-server-pool/fastify-worker_threads/src/worker.ts
examples/typescript/websocket-server-pool/ws-hybrid/src/request-handler-worker.ts
examples/typescript/websocket-server-pool/ws-worker_threads/src/pool.ts
examples/typescript/websocket-server-pool/ws-worker_threads/src/worker.ts
src/pools/abstract-pool.ts
src/pools/selection-strategies/fair-share-worker-choice-strategy.ts
src/pools/utils.ts
src/priority-queue.ts
src/utils.ts
tests/priority-queue.test.mjs
tests/utils.test.mjs

index ca5de3c1821de7bed57680fe1a3acd4aae3e398a..4be3826f7e8165bb698e9c9dd21617b8b0f26160 100644 (file)
@@ -18,7 +18,7 @@ const tasksMap = generateRandomTasksMap(60, 20)
 
 function loopSelect (tasksMap) {
   let minKey
-  let minValue = Infinity
+  let minValue = Number.POSITIVE_INFINITY
   for (const [key, value] of tasksMap) {
     if (value === 0) {
       return key
index 6db45d5f0e7a413cd2e14ed4b2b17f7f326e4ecf..9b35949c970daf7a885bdd99c600f9814ab4bdfc 100644 (file)
@@ -1,9 +1,9 @@
 import type { URL } from 'node:url'
 
 import type { AxiosRequestConfig } from 'axios'
-import {
-  type RequestInfo as NodeFetchRequestInfo,
-  type RequestInit as NodeFetchRequestInit
+import type {
+  RequestInfo as NodeFetchRequestInfo,
+  RequestInit as NodeFetchRequestInit
 } from 'node-fetch'
 
 export interface WorkerData {
index 98ca45deea0be0c1dab6bb92ff558555d9eee271..4659e00aee4acb7a91ada465a294fa4fafc7b5db 100644 (file)
@@ -39,7 +39,9 @@ class ExpressWorker extends ClusterWorker<WorkerData, WorkerResponse> {
     application.get('/api/factorial/:number', (req: Request, res: Response) => {
       const { number } = req.params
       res
-        .send({ number: ExpressWorker.factorial(parseInt(number)).toString() })
+        .send({
+          number: ExpressWorker.factorial(Number.parseInt(number)).toString()
+        })
         .end()
     })
 
index 7ba9f374f5fa248012fab50afb72e508f8391de4..bde3ad4e629c97941870c97c894e7442195fc3c0 100644 (file)
@@ -8,12 +8,12 @@ import {
   DynamicThreadPool
 } from 'poolifier'
 
-import {
-  type ClusterWorkerData,
-  type ClusterWorkerResponse,
-  type DataPayload,
-  type ThreadWorkerData,
-  type ThreadWorkerResponse
+import type {
+  ClusterWorkerData,
+  ClusterWorkerResponse,
+  DataPayload,
+  ThreadWorkerData,
+  ThreadWorkerResponse
 } from './types.js'
 
 const emptyFunction = (): void => {
@@ -63,7 +63,7 @@ ClusterWorkerResponse
     application.get('/api/factorial/:number', (req: Request, res: Response) => {
       const { number } = req.params
       ExpressWorker.requestHandlerPool
-        .execute({ data: { number: parseInt(number) } }, 'factorial')
+        .execute({ data: { number: Number.parseInt(number) } }, 'factorial')
         .then(response => {
           return res.send(response.data).end()
         })
index b7ff8b166e40bc19d55dfadcf6038f15554cbb8d..5dbc11375668513fdf1d1ce9f7a28607202398ac 100644 (file)
@@ -1,9 +1,9 @@
 import { ThreadWorker } from 'poolifier'
 
-import {
-  type DataPayload,
-  type ThreadWorkerData,
-  type ThreadWorkerResponse
+import type {
+  DataPayload,
+  ThreadWorkerData,
+  ThreadWorkerResponse
 } from './types.js'
 
 class RequestHandlerWorker<
index fc0f2d84bb7b19a2b05455abea5915ef0959aa2d..e0cb704218b817d638e986826fd2e078d36ad92e 100644 (file)
@@ -33,7 +33,7 @@ expressApp.all('/api/echo', (req: Request, res: Response) => {
 expressApp.get('/api/factorial/:number', (req: Request, res: Response) => {
   const { number } = req.params
   requestHandlerPool
-    .execute({ body: { number: parseInt(number) } }, 'factorial')
+    .execute({ body: { number: Number.parseInt(number) } }, 'factorial')
     .then(response => {
       return res.send(response.body).end()
     })
index 98ae657d4a764bc39e07650db35add4c92718be5..0f6a7accb63ce881e49a3a06b34647297fd6a064 100644 (file)
@@ -3,11 +3,7 @@ import { fileURLToPath } from 'node:url'
 
 import { availableParallelism, DynamicThreadPool } from 'poolifier'
 
-import {
-  type BodyPayload,
-  type WorkerData,
-  type WorkerResponse
-} from './types.js'
+import type { BodyPayload, WorkerData, WorkerResponse } from './types.js'
 
 const workerFile = join(
   dirname(fileURLToPath(import.meta.url)),
index 18e5c8a3cef5aef91512f609f30595c315c6b47c..09810907704576fedd1e337afb09b59560246551 100644 (file)
@@ -1,10 +1,6 @@
 import { ThreadWorker } from 'poolifier'
 
-import {
-  type BodyPayload,
-  type WorkerData,
-  type WorkerResponse
-} from './types.js'
+import type { BodyPayload, WorkerData, WorkerResponse } from './types.js'
 
 class RequestHandlerWorker<
   Data extends WorkerData<BodyPayload>,
index 018cac59cf6762769e0cc713b687a2463832718f..166bfd330a00fa3efe91af3eab84e3d2966edd17 100644 (file)
@@ -3,10 +3,7 @@ import type { TransferListItem } from 'node:worker_threads'
 import type * as fastify from 'fastify'
 import type { DynamicThreadPool } from 'poolifier'
 
-import {
-  type ThreadWorkerData,
-  type ThreadWorkerResponse
-} from '../../src/types.ts'
+import type { ThreadWorkerData, ThreadWorkerResponse } from '../../src/types.ts'
 
 declare module 'fastify' {
   export interface FastifyInstance extends fastify.FastifyInstance {
index f105d7af3a10395421b118e3ec308445ea0a63a4..b4369082833e5409823401a9c61608765d97138a 100644 (file)
@@ -4,10 +4,10 @@ import type { FastifyPluginCallback } from 'fastify'
 import fp from 'fastify-plugin'
 import { availableParallelism, DynamicThreadPool } from 'poolifier'
 
-import {
-  type FastifyPoolifierOptions,
-  type ThreadWorkerData,
-  type ThreadWorkerResponse
+import type {
+  FastifyPoolifierOptions,
+  ThreadWorkerData,
+  ThreadWorkerResponse
 } from './types.js'
 
 const fastifyPoolifierPlugin: FastifyPluginCallback<FastifyPoolifierOptions> = (
index b7ff8b166e40bc19d55dfadcf6038f15554cbb8d..5dbc11375668513fdf1d1ce9f7a28607202398ac 100644 (file)
@@ -1,9 +1,9 @@
 import { ThreadWorker } from 'poolifier'
 
-import {
-  type DataPayload,
-  type ThreadWorkerData,
-  type ThreadWorkerResponse
+import type {
+  DataPayload,
+  ThreadWorkerData,
+  ThreadWorkerResponse
 } from './types.js'
 
 class RequestHandlerWorker<
index 450a2aeaf2c7fda086aa19d117c5af5c20636ed2..c031d287d34a640b368839fe8ef6936d47a6cf9a 100644 (file)
@@ -4,10 +4,10 @@ import type { FastifyPluginCallback } from 'fastify'
 import fp from 'fastify-plugin'
 import { availableParallelism, DynamicThreadPool } from 'poolifier'
 
-import {
-  type FastifyPoolifierOptions,
-  type WorkerData,
-  type WorkerResponse
+import type {
+  FastifyPoolifierOptions,
+  WorkerData,
+  WorkerResponse
 } from './types.js'
 
 const fastifyPoolifierPlugin: FastifyPluginCallback<FastifyPoolifierOptions> = (
index 18e5c8a3cef5aef91512f609f30595c315c6b47c..09810907704576fedd1e337afb09b59560246551 100644 (file)
@@ -1,10 +1,6 @@
 import { ThreadWorker } from 'poolifier'
 
-import {
-  type BodyPayload,
-  type WorkerData,
-  type WorkerResponse
-} from './types.js'
+import type { BodyPayload, WorkerData, WorkerResponse } from './types.js'
 
 class RequestHandlerWorker<
   Data extends WorkerData<BodyPayload>,
index 004dd3dbc6fcded778bf88b2c156b8d1184f61ef..99d303319a19449ee81dcd6107e3227a28c4b68b 100644 (file)
@@ -1,9 +1,9 @@
 import { ThreadWorker } from 'poolifier'
 
-import {
-  type DataPayload,
-  type ThreadWorkerData,
-  type ThreadWorkerResponse
+import type {
+  DataPayload,
+  ThreadWorkerData,
+  ThreadWorkerResponse
 } from './types.js'
 
 class RequestHandlerWorker<
index 45d458d53f8993a8baf8697e8709abd64b679849..ac8b9c8657049774d9cccba0bf2173e1b6fe07d8 100644 (file)
@@ -3,11 +3,7 @@ import { fileURLToPath } from 'node:url'
 
 import { availableParallelism, DynamicThreadPool } from 'poolifier'
 
-import {
-  type DataPayload,
-  type WorkerData,
-  type WorkerResponse
-} from './types.js'
+import type { DataPayload, WorkerData, WorkerResponse } from './types.js'
 
 const workerFile = join(
   dirname(fileURLToPath(import.meta.url)),
index e1b67193a2e944de72ef04e16871793eefa646b7..92baa166073a0784025fe77d4b4dfb67ed7f1b2f 100644 (file)
@@ -1,10 +1,6 @@
 import { ThreadWorker } from 'poolifier'
 
-import {
-  type DataPayload,
-  type WorkerData,
-  type WorkerResponse
-} from './types.js'
+import type { DataPayload, WorkerData, WorkerResponse } from './types.js'
 
 class RequestHandlerWorker<
   Data extends WorkerData<DataPayload>,
index 95d3970fdbd859f71ce67e5dd4b779bc6afeddcc..a23c7983bfc652fbfcb8ece4a75853dbed270ac5 100644 (file)
@@ -376,14 +376,16 @@ export abstract class AbstractPool<
           minimum: round(
             min(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.runTime.minimum ?? Infinity
+                workerNode =>
+                  workerNode.usage.runTime.minimum ?? Number.POSITIVE_INFINITY
               )
             )
           ),
           maximum: round(
             max(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.runTime.maximum ?? -Infinity
+                workerNode =>
+                  workerNode.usage.runTime.maximum ?? Number.NEGATIVE_INFINITY
               )
             )
           ),
@@ -419,14 +421,16 @@ export abstract class AbstractPool<
           minimum: round(
             min(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.waitTime.minimum ?? Infinity
+                workerNode =>
+                  workerNode.usage.waitTime.minimum ?? Number.POSITIVE_INFINITY
               )
             )
           ),
           maximum: round(
             max(
               ...this.workerNodes.map(
-                workerNode => workerNode.usage.waitTime.maximum ?? -Infinity
+                workerNode =>
+                  workerNode.usage.waitTime.maximum ?? Number.NEGATIVE_INFINITY
               )
             )
           ),
@@ -463,14 +467,18 @@ export abstract class AbstractPool<
             minimum: round(
               min(
                 ...this.workerNodes.map(
-                  workerNode => workerNode.usage.elu.idle.minimum ?? Infinity
+                  workerNode =>
+                    workerNode.usage.elu.idle.minimum ??
+                    Number.POSITIVE_INFINITY
                 )
               )
             ),
             maximum: round(
               max(
                 ...this.workerNodes.map(
-                  workerNode => workerNode.usage.elu.idle.maximum ?? -Infinity
+                  workerNode =>
+                    workerNode.usage.elu.idle.maximum ??
+                    Number.NEGATIVE_INFINITY
                 )
               )
             ),
@@ -503,14 +511,18 @@ export abstract class AbstractPool<
             minimum: round(
               min(
                 ...this.workerNodes.map(
-                  workerNode => workerNode.usage.elu.active.minimum ?? Infinity
+                  workerNode =>
+                    workerNode.usage.elu.active.minimum ??
+                    Number.POSITIVE_INFINITY
                 )
               )
             ),
             maximum: round(
               max(
                 ...this.workerNodes.map(
-                  workerNode => workerNode.usage.elu.active.maximum ?? -Infinity
+                  workerNode =>
+                    workerNode.usage.elu.active.maximum ??
+                    Number.NEGATIVE_INFINITY
                 )
               )
             ),
@@ -1495,7 +1507,8 @@ export abstract class AbstractPool<
     ) {
       workerNode.usage.runTime.aggregate = min(
         ...this.workerNodes.map(
-          workerNode => workerNode.usage.runTime.aggregate ?? Infinity
+          workerNode =>
+            workerNode.usage.runTime.aggregate ?? Number.POSITIVE_INFINITY
         )
       )
     }
@@ -1505,7 +1518,8 @@ export abstract class AbstractPool<
     ) {
       workerNode.usage.waitTime.aggregate = min(
         ...this.workerNodes.map(
-          workerNode => workerNode.usage.waitTime.aggregate ?? Infinity
+          workerNode =>
+            workerNode.usage.waitTime.aggregate ?? Number.POSITIVE_INFINITY
         )
       )
     }
@@ -1515,7 +1529,8 @@ export abstract class AbstractPool<
     ) {
       workerNode.usage.elu.active.aggregate = min(
         ...this.workerNodes.map(
-          workerNode => workerNode.usage.elu.active.aggregate ?? Infinity
+          workerNode =>
+            workerNode.usage.elu.active.aggregate ?? Number.POSITIVE_INFINITY
         )
       )
     }
index 357b770a1f3eec275e87e8d7702ed42a8fd26bbd..d1a4919d70184950dcacdf4596db552579bc9fb1 100644 (file)
@@ -136,7 +136,7 @@ export class FairShareWorkerChoiceStrategy<
       this.pool.workerNodes[workerNodeKey]?.strategyData
         ?.virtualTaskEndTimestamp
     const now = performance.now()
-    return now < (virtualTaskEndTimestamp ?? -Infinity)
+    return now < (virtualTaskEndTimestamp ?? Number.NEGATIVE_INFINITY)
       ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       virtualTaskEndTimestamp!
       : now
index c3ca698cac24da378dddf9451031a304b1a5c5a3..e69725df102ed2ea083512b76f5dce75139a6894 100644 (file)
@@ -226,11 +226,11 @@ const updateMeasurementStatistics = (
       (measurementStatistics.aggregate ?? 0) + measurementValue
     measurementStatistics.minimum = min(
       measurementValue,
-      measurementStatistics.minimum ?? Infinity
+      measurementStatistics.minimum ?? Number.POSITIVE_INFINITY
     )
     measurementStatistics.maximum = max(
       measurementValue,
-      measurementStatistics.maximum ?? -Infinity
+      measurementStatistics.maximum ?? Number.NEGATIVE_INFINITY
     )
     if (measurementRequirements.average || measurementRequirements.median) {
       measurementStatistics.history.push(measurementValue)
index 8e9c1ae2db52fb4eba012fcc27be33d48b7e2885..b4d70b5ea8424c444570ac8acc4b03d2e33d4530 100644 (file)
@@ -30,7 +30,7 @@ export class PriorityQueue<T> {
    * The number of filled prioritized buckets.
    */
   public get buckets (): number {
-    return this.bucketSize === Infinity
+    return this.bucketSize === Number.POSITIVE_INFINITY
       ? 1
       : Math.trunc(this.nodeArray.length / this.bucketSize)
   }
@@ -38,10 +38,13 @@ export class PriorityQueue<T> {
   /**
    * Constructs a priority queue.
    *
-   * @param bucketSize - Prioritized bucket size. @defaultValue Infinity
+   * @param bucketSize - Prioritized bucket size. @defaultValue Number.POSITIVE_INFINITY
    */
-  public constructor (bucketSize = Infinity) {
-    if (bucketSize !== Infinity && !Number.isSafeInteger(bucketSize)) {
+  public constructor (bucketSize = Number.POSITIVE_INFINITY) {
+    if (
+      bucketSize !== Number.POSITIVE_INFINITY &&
+      !Number.isSafeInteger(bucketSize)
+    ) {
       throw new TypeError('bucketSize must be an integer')
     }
     if (bucketSize < 1) {
@@ -61,7 +64,9 @@ export class PriorityQueue<T> {
   public enqueue (data: T, priority?: number): number {
     priority = priority ?? 0
     const startIndex =
-      this.bucketSize === Infinity ? 0 : this.buckets * this.bucketSize
+      this.bucketSize === Number.POSITIVE_INFINITY
+        ? 0
+        : this.buckets * this.bucketSize
     let inserted = false
     for (let index = startIndex; index < this.nodeArray.length; index++) {
       if (this.nodeArray[index].priority > priority) {
@@ -83,7 +88,7 @@ export class PriorityQueue<T> {
    * @returns The dequeued data or `undefined` if the priority queue is empty.
    */
   public dequeue (bucket = 0): T | undefined {
-    if (this.bucketSize !== Infinity && bucket > 0) {
+    if (this.bucketSize !== Number.POSITIVE_INFINITY && bucket > 0) {
       while (bucket > 0) {
         const index = bucket * this.bucketSize
         // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
index dd839bc491b622aa871b876424474d24abdfb44e..f38221692c8e76b06a57605f8a9129e198796cec 100644 (file)
@@ -174,25 +174,31 @@ export const secureRandom = (): number => {
 
 /**
  * Returns the minimum of the given numbers.
- * If no numbers are given, `Infinity` is returned.
+ * If no numbers are given, `Number.POSITIVE_INFINITY` is returned.
  *
  * @param args - The numbers to get the minimum of.
  * @returns The minimum of the given numbers.
  * @internal
  */
 export const min = (...args: number[]): number =>
-  args.reduce((minimum, num) => (minimum < num ? minimum : num), Infinity)
+  args.reduce(
+    (minimum, num) => (minimum < num ? minimum : num),
+    Number.POSITIVE_INFINITY
+  )
 
 /**
  * Returns the maximum of the given numbers.
- * If no numbers are given, `-Infinity` is returned.
+ * If no numbers are given, `Number.NEGATIVE_INFINITY` is returned.
  *
  * @param args - The numbers to get the maximum of.
  * @returns The maximum of the given numbers.
  * @internal
  */
 export const max = (...args: number[]): number =>
-  args.reduce((maximum, num) => (maximum > num ? maximum : num), -Infinity)
+  args.reduce(
+    (maximum, num) => (maximum > num ? maximum : num),
+    Number.NEGATIVE_INFINITY
+  )
 
 /**
  * Wraps a function so that it can only be called once.
index f3da873405855449119dba52df325992a84f39a0..00ecb33f9d3595840e7b203bd28e6432d8ab4797 100644 (file)
@@ -14,7 +14,7 @@ describe('Priority queue test suite', () => {
       new RangeError('bucketSize must be greater than or equal to 1')
     )
     let priorityQueue = new PriorityQueue()
-    expect(priorityQueue.bucketSize).toBe(Infinity)
+    expect(priorityQueue.bucketSize).toBe(Number.POSITIVE_INFINITY)
     expect(priorityQueue.buckets).toBe(1)
     expect(priorityQueue.size).toBe(0)
     expect(priorityQueue.maxSize).toBe(0)
index b3c79d9c0e086f0dcd125d857a81ba808fcf02a3..6e97797e35bfc4228e750c3ddf519b625667da77 100644 (file)
@@ -151,7 +151,7 @@ describe('Utils test suite', () => {
     expect(isAsyncFunction([])).toBe(false)
     expect(isAsyncFunction(new Date())).toBe(false)
     // eslint-disable-next-line prefer-regex-literals
-    expect(isAsyncFunction(new RegExp('[a-z]', 'i'))).toBe(false)
+    expect(isAsyncFunction(/[a-z]/i)).toBe(false)
     expect(isAsyncFunction(new Error())).toBe(false)
     expect(isAsyncFunction(new Map())).toBe(false)
     expect(isAsyncFunction(new Set())).toBe(false)
@@ -207,14 +207,14 @@ describe('Utils test suite', () => {
   })
 
   it('Verify min() behavior', () => {
-    expect(min()).toBe(Infinity)
+    expect(min()).toBe(Number.POSITIVE_INFINITY)
     expect(min(1, 2)).toBe(1)
     expect(min(2, 1)).toBe(1)
     expect(min(1, 1)).toBe(1)
   })
 
   it('Verify max() behavior', () => {
-    expect(max()).toBe(-Infinity)
+    expect(max()).toBe(Number.NEGATIVE_INFINITY)
     expect(max(1, 2)).toBe(2)
     expect(max(2, 1)).toBe(2)
     expect(max(1, 1)).toBe(1)