Initial Commit
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# `RoundRobinStrategy`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
`RoundRobinStrategy` selects available workers in rotation order. The pointer is internal to the instance — two strategies sharing a pool advance independently — and clamps when the pool shrinks below the current index so iteration stays in bounds. Round-robin is the right default for homogeneous worker pools where every worker has similar capacity, weight, and latency characteristics.
|
||||
|
||||
## Features
|
||||
|
||||
- Cyclic order across eligible workers (filtered via `AbstractLoadBalancingStrategy.filterAvailableWorkers`).
|
||||
- `reset()` zeroes the pointer for deterministic test setups.
|
||||
- Pool-shrink-safe: if the pointer index is now beyond the available-worker list, it clamps to zero.
|
||||
- `getName()` returns `"round-robin"`.
|
||||
- No external dependencies (no `Clock`, no `Rng`, no `IdGenerator`).
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { RoundRobinStrategy } from "@suaveplan/queue-distribution/load-balancing/round-robin/round-robin";
|
||||
import { LocalWorker } from "@suaveplan/queue-distribution/worker/local/local";
|
||||
import { WorkerPool } from "@suaveplan/queue-distribution/pool/pool";
|
||||
|
||||
const pool = new WorkerPool();
|
||||
pool.addWorker(new LocalWorker({}, { id: "a" }));
|
||||
pool.addWorker(new LocalWorker({}, { id: "b" }));
|
||||
const strategy = new RoundRobinStrategy();
|
||||
strategy.selectWorker(pool.getAvailableWorkers()); // worker "a"
|
||||
strategy.selectWorker(pool.getAvailableWorkers()); // worker "b"
|
||||
strategy.selectWorker(pool.getAvailableWorkers()); // worker "a"
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
Combine `RoundRobinStrategy` with a `WorkerManager` to drive task dispatch.
|
||||
|
||||
```ts
|
||||
import { WorkerManager } from "@suaveplan/queue-distribution/manager/manager";
|
||||
import { RoundRobinStrategy } from "@suaveplan/queue-distribution/load-balancing/round-robin/round-robin";
|
||||
import { WorkerPool } from "@suaveplan/queue-distribution/pool/pool";
|
||||
|
||||
const pool = new WorkerPool();
|
||||
// ... add workers ...
|
||||
const manager = new WorkerManager(pool, {
|
||||
balancer: new RoundRobinStrategy(),
|
||||
autoHealthCheck: false,
|
||||
maxTaskRetries: 2,
|
||||
});
|
||||
|
||||
await manager.assignTask(task, input);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `class RoundRobinStrategy extends AbstractLoadBalancingStrategy`.
|
||||
- `selectWorker(workers, task?): Worker | null` — return next eligible worker or `null`.
|
||||
- `reset(): void` — set pointer to zero.
|
||||
- `getName(): string` — returns `"round-robin"`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The strategy stores its pointer with a `#`-prefixed private field so subclasses cannot tamper with it. The clamp-on-shrink behaviour is non-obvious but matters: if a worker is removed from the pool mid-dispatch, the next selection might otherwise reach into a non-existent index. The clamp keeps iteration bounded without needing a synchronisation primitive between pool-shrink events and strategy state.
|
||||
Reference in New Issue
Block a user