return true
}
+ /** @inheritDoc */
+ public update (): boolean {
+ for (const [workerNodeKey] of this.pool.workerNodes.entries()) {
+ this.computeWorkerVirtualTaskTimestamp(workerNodeKey)
+ }
+ return true
+ }
+
/** @inheritDoc */
public choose (): number {
let minWorkerVirtualTaskEndTimestamp = Infinity
let chosenWorkerNodeKey!: number
for (const [workerNodeKey] of this.pool.workerNodes.entries()) {
- this.computeWorkerVirtualTaskTimestamp(workerNodeKey)
const workerVirtualTaskEndTimestamp =
this.workersVirtualTaskTimestamp[workerNodeKey]?.end ?? 0
if (workerVirtualTaskEndTimestamp < minWorkerVirtualTaskEndTimestamp) {
: this.pool.workerNodes[workerNodeKey].tasksUsage.avgRunTime
this.workersVirtualTaskTimestamp[workerNodeKey] = {
start: workerVirtualTaskStartTimestamp,
- end: workerVirtualTaskStartTimestamp + (workerVirtualTaskTRunTime ?? 0)
+ end: workerVirtualTaskStartTimestamp + workerVirtualTaskTRunTime
}
}
}
*/
readonly requiredStatistics: RequiredStatistics
/**
- * Resets strategy internals (counters, statistics, etc.).
+ * Resets strategy internals.
*/
reset: () => boolean
+ /**
+ * Updates strategy internals.
+ *
+ * @returns `true` if the update is successful, `false` otherwise.
+ */
+ update: () => boolean
/**
* Chooses a worker node in the pool and returns its key.
*/
* Removes a worker node key from strategy internals.
*
* @param workerNodeKey - The worker node key.
+ * @returns `true` if the worker node key is removed, `false` otherwise.
*/
remove: (workerNodeKey: number) => boolean
/**
return true
}
+ /** @inheritDoc */
+ public update (): boolean {
+ return true
+ }
+
/** @inheritDoc */
public choose (): number {
const chosenWorkerNodeKey = this.currentWorkerNodeId
- const workerVirtualTaskRunTime = this.workerVirtualTaskRunTime ?? 0
- const workerTaskWeight =
+ const workerVirtualTaskRunTime = this.workerVirtualTaskRunTime
+ const workerWeight =
this.opts.weights?.[chosenWorkerNodeKey] ?? this.defaultWorkerWeight
- if (workerVirtualTaskRunTime < workerTaskWeight) {
+ if (workerVirtualTaskRunTime < workerWeight) {
this.workerVirtualTaskRunTime =
workerVirtualTaskRunTime +
- (this.getWorkerVirtualTaskRunTime(chosenWorkerNodeKey) ?? 0)
+ this.getWorkerVirtualTaskRunTime(chosenWorkerNodeKey)
} else {
this.currentWorkerNodeId =
this.currentWorkerNodeId === this.pool.workerNodes.length - 1
promises.push(pool.execute())
}
await Promise.all(promises)
+ for (const workerNode of pool.workerNodes) {
+ expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
+ expect(workerNode.tasksUsage.medRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.medRunTime).toBe(0)
+ }
expect(
pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
pool.workerChoiceStrategyContext.workerChoiceStrategy
promises.push(pool.execute())
}
await Promise.all(promises)
+ for (const workerNode of pool.workerNodes) {
+ expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
+ expect(workerNode.tasksUsage.medRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.medRunTime).toBe(0)
+ }
expect(
pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
pool.workerChoiceStrategyContext.workerChoiceStrategy
expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
expect(workerNode.tasksUsage.avgRunTime).toBe(0)
expect(workerNode.tasksUsage.medRunTime).toBeDefined()
- expect(workerNode.tasksUsage.medRunTime).toBeGreaterThan(0)
+ expect(workerNode.tasksUsage.medRunTime).toBeGreaterThanOrEqual(0)
}
expect(
pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
promises.push(pool.execute())
}
await Promise.all(promises)
+ for (const workerNode of pool.workerNodes) {
+ expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
+ expect(workerNode.tasksUsage.medRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.medRunTime).toBe(0)
+ }
expect(
pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
pool.workerChoiceStrategyContext.workerChoiceStrategy
)
// TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
const promises = []
- const maxMultiplier =
- pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
- pool.workerChoiceStrategyContext.workerChoiceStrategy
- ).defaultWorkerWeight * 50
+ const maxMultiplier = 2
for (let i = 0; i < max * maxMultiplier; i++) {
promises.push(pool.execute())
}
await Promise.all(promises)
+ for (const workerNode of pool.workerNodes) {
+ expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
+ expect(workerNode.tasksUsage.medRunTime).toBeDefined()
+ expect(workerNode.tasksUsage.medRunTime).toBe(0)
+ }
expect(
pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
pool.workerChoiceStrategyContext.workerChoiceStrategy
expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
expect(workerNode.tasksUsage.avgRunTime).toBe(0)
expect(workerNode.tasksUsage.medRunTime).toBeDefined()
- expect(workerNode.tasksUsage.medRunTime).toBeGreaterThan(0)
+ expect(workerNode.tasksUsage.medRunTime).toBeGreaterThanOrEqual(0)
}
expect(
pool.workerChoiceStrategyContext.workerChoiceStrategies.get(