perf: allow finer grained control over tasks usage computation
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 4 Apr 2023 12:36:34 +0000 (14:36 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 4 Apr 2023 12:36:34 +0000 (14:36 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
CHANGELOG.md
src/pools/abstract-pool.ts
src/pools/selection-strategies/abstract-worker-choice-strategy.ts
src/pools/selection-strategies/fair-share-worker-choice-strategy.ts
src/pools/selection-strategies/less-busy-worker-choice-strategy.ts
src/pools/selection-strategies/selection-strategies-types.ts
src/pools/selection-strategies/weighted-round-robin-worker-choice-strategy.ts
tests/pools/selection-strategies/selection-strategies.test.js

index 81f7163472995bf521ab910f490ea731093620d3..38457a2b6715c0473c92b0e56a43fbe3bc138924 100644 (file)
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+### Added
+
+- Add `LESS_BUSY` worker choice strategy.
+
+### Changed
+
+- Optimize worker storage in pool.
+- Optimize worker alive status check.
+- BREAKING CHANGE: Rename worker choice strategy `LESS_RECENTLY_USED` to `LESS_USED`.
+- Optimize `LESS_USED` worker choice strategy.
+- Update benchmarks versus external threads pools.
+- Optimize tasks usage statistics requirements for worker choice strategy.
+
+### Fixed
+
+- Ensure trimmable characters are checked at pool initialization.
+- Fix message id integer overflow.
+- Fix pool worker removal in worker choice strategy internals.
+- Fix package publication with pnpm.
+
 ## [2.4.0-3] - 2023-04-04
 
 ### Added
index 66b1ea1da3f3ba47d93cda9c94d2b2a19cc63ac3..1ce8c25ec8f3a783c2ce0802e39d81bd60e82bf2 100644 (file)
@@ -261,7 +261,10 @@ export abstract class AbstractPool<
     }
     if (this.workerChoiceStrategyContext.getRequiredStatistics().runTime) {
       workerTasksUsage.runTime += message.taskRunTime ?? 0
-      if (workerTasksUsage.run !== 0) {
+      if (
+        this.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime &&
+        workerTasksUsage.run !== 0
+      ) {
         workerTasksUsage.avgRunTime =
           workerTasksUsage.runTime / workerTasksUsage.run
       }
index b181273375777830ce5c2e5ebf1a504227994dcd..5c2a553d187b92fe5793fac750a7ae2c5d0d9e82 100644 (file)
@@ -22,7 +22,8 @@ export abstract class AbstractWorkerChoiceStrategy<
   public readonly isDynamicPool: boolean
   /** {@inheritDoc} */
   public requiredStatistics: RequiredStatistics = {
-    runTime: false
+    runTime: false,
+    avgRunTime: false
   }
 
   /**
index 57aafe3759544df2e33bdf67ff0c4185b12f7f7e..7ef287484f1d00a0002a86a6fd977b99d514e183 100644 (file)
@@ -30,7 +30,8 @@ export class FairShareWorkerChoiceStrategy<
   implements IWorkerChoiceStrategy {
   /** {@inheritDoc} */
   public readonly requiredStatistics: RequiredStatistics = {
-    runTime: true
+    runTime: true,
+    avgRunTime: true
   }
 
   /**
index 75109a2b2848af781704a0c41965cf7180ea27e7..87ee1ef88f16714d4271a5ba671686d122667f35 100644 (file)
@@ -21,7 +21,8 @@ export class LessBusyWorkerChoiceStrategy<
   implements IWorkerChoiceStrategy {
   /** {@inheritDoc} */
   public readonly requiredStatistics: RequiredStatistics = {
-    runTime: true
+    runTime: true,
+    avgRunTime: false
   }
 
   /** {@inheritDoc} */
index c098768533fcced20246044d5411ad1ebb7bb76c..fb864c5b08ffc31a3cb1336225d31f285b0ce240 100644 (file)
@@ -34,6 +34,7 @@ export type WorkerChoiceStrategy = keyof typeof WorkerChoiceStrategies
  */
 export interface RequiredStatistics {
   runTime: boolean
+  avgRunTime: boolean
 }
 
 /**
index ad42ee90602797171bcbb7d3cc33672817d64ec4..3709cce409b4ba988a728f81f0f8c6eb65f205f8 100644 (file)
@@ -32,7 +32,8 @@ export class WeightedRoundRobinWorkerChoiceStrategy<
   implements IWorkerChoiceStrategy {
   /** {@inheritDoc} */
   public readonly requiredStatistics: RequiredStatistics = {
-    runTime: true
+    runTime: true,
+    avgRunTime: true
   }
 
   /**
index abfbdb9ac85a339b98beaf2d02081f00259b03cc..7187a9007179bb5f7afbf511d055f8a5507d7fab 100644 (file)
@@ -72,6 +72,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(false)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(false)
     await pool.destroy()
     pool = new DynamicThreadPool(
       min,
@@ -82,6 +85,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(false)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(false)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -213,6 +219,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(false)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(false)
     await pool.destroy()
     pool = new DynamicThreadPool(
       min,
@@ -223,6 +232,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(false)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(false)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -295,6 +307,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(true)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(false)
     await pool.destroy()
     pool = new DynamicThreadPool(
       min,
@@ -305,6 +320,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(true)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(false)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -389,6 +407,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(true)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(true)
     await pool.destroy()
     pool = new DynamicThreadPool(
       min,
@@ -399,6 +420,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(true)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(true)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -549,6 +573,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(true)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(true)
     await pool.destroy()
     pool = new DynamicThreadPool(
       min,
@@ -559,6 +586,9 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
     ).toBe(true)
+    expect(
+      pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
+    ).toBe(true)
     // We need to clean up the resources after our test
     await pool.destroy()
   })