Files
skills/docs/foundation/flow/queue-distribution/README.md
2026-05-29 08:20:56 +01:00

130 lines
20 KiB
Markdown

# @suaveplan/queue-distribution - Worker-pool distribution layer: load-balancing strategies (round-robin / least-busy / weighted), worker pool, manager with retry + health checks, in-process LocalWorker. Transport-agnostic — HTTP and worker-thread plugins ship as separate packages.
## Summary
Worker-pool distribution layer: load-balancing strategies, worker pool management, manager with retry and health checks, in-process `LocalWorker`. Transport-agnostic — HTTP and worker-thread transports ship as separate plugin packages (`@suaveplan/queue-distribution-http`, `@suaveplan/queue-distribution-worker-thread`).
The package is decoupled from `@suaveplan/queue`'s `Job` model: distribution operates on a minimal `DistributedTask<I, O>` contract so it can serve any consumer that produces typed work units (queue, batch, RPC, agent dispatch).
<!-- begin:auto-docs -->
## Documentation tree
- [errors](./src/errors/queue-distribution-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [queue-distribution-error](./src/errors/queue-distribution-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [internal](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [noop-logger](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [manager-dispatch](./src/manager/manager-dispatch.md) — `dispatchWithRetry` is the core retry loop of `WorkerManager`. It picks a worker via the configured `LoadBalancingStrat…
- [manager-supervisor](./src/manager/manager-supervisor.md) — The supervisor module owns the worker-health side of `WorkerManager`: periodic health checks across the pool, restart o…
- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [observability](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [instruments](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- abstract-metrics — `abstract-metrics.ts` carries the…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [abstract-metrics](./src/worker/abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->- abstract-metrics — `abstract-metrics.ts` carries the…
<!-- end:auto-docs --> - [queue-distribution-error](./src/errors/queue-distribution-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_- [internal](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [noop-logger](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [manager-dispatch](./src/manager/manager-dispatch.md) — `dispatchWithRetry` is the core retry loop of `WorkerManager`. It picks a worker via the configured `LoadBalancingStrat…
- [manager-supervisor](./src/manager/manager-supervisor.md) — The supervisor module owns the worker-health side of `WorkerManager`: periodic health checks across the pool, restart o…
- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [instruments](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract-metrics](./src/worker/abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_- [queue-distribution-error](./src/errors/queue-distribution-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_- [internal](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [noop-logger](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [manager-dispatch](./src/manager/manager-dispatch.md) — `dispatchWithRetry` is the core retry loop of `WorkerManager`. It picks a worker via the configured `LoadBalancingStrat…
- [manager-supervisor](./src/manager/manager-supervisor.md) — The supervisor module owns the worker-health side of `WorkerManager`: periodic health checks across the pool, restart o…
- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [instruments](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_- abstract-metrics — `abstract…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract-metrics](./src/worker/abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_- abstract-metrics — `abstract…
- [queue-distribution-error](./src/errors/queue-distribution-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_- [internal](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [noop-logger](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [manager-dispatch](./src/manager/manager-dispatch.md) — `dispatchWithRetry` is the core retry loop of `WorkerManager`. It picks a worker via the configured `LoadBalancingStrat…
- [manager-supervisor](./src/manager/manager-supervisor.md) — The supervisor module owns the worker-health side of `WorkerManager`: periodic health checks across the pool, restart o…
- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [instruments](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_- abstract-metrics — `abstract-metrics.ts` carries th…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract-metrics](./src/worker/abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_- abstract-metrics — `abstract-metrics.ts` carries th…
- [queue-distribution-error](./src/errors/queue-distribution-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_ - [health-checker](./src/health-checker/health-checker.md) — <!-- begin:auto-docs --> _(no submodules)_- [internal](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ - [noop-logger](./src/internal/noop-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_ - [base](./src/load-balancing/base/base.md) — <!-- begin:auto-docs --> _(no submodules)_- [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_ - [least-busy](./src/load-balancing/least-busy/least-busy.md) — <!-- begin:auto-docs --> _(no submodules)_- [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_ - [round-robin](./src/load-balancing/round-robin/round-robin.md) — <!-- begin:auto-docs --> _(no submodules)_- [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_ - [weighted](./src/load-balancing/weighted/weighted.md) — <!-- begin:auto-docs --> _(no submodules)_- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_ - [manager-dispatch](./src/manager/manager-dispatch.md) — `dispatchWithRetry` is the core retry loop of `WorkerManager`. It picks a worker via the configured `LoadBalancingStrat…
- [manager-supervisor](./src/manager/manager-supervisor.md) — The supervisor module owns the worker-health side of `WorkerManager`: periodic health checks across the pool, restart o…
- [manager](./src/manager/manager.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_ - [instruments](./src/observability/instruments.md) — <!-- begin:auto-docs --> _(no submodules)_- [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_ - [pool](./src/pool/pool.md) — <!-- begin:auto-docs --> _(no submodules)_- [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_ - [task](./src/task/task.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_ - [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_ - [abstract-metrics](./src/worker/abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./src/worker/abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_ - [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_ - [local](./src/worker/local/local.md) — <!-- begin:auto-docs --> _(no submodules)_ - [worker](./src/worker/worker.md) — <!-- begin:auto-docs --> _(no submodules)_
## Install
```bash
bun add @suaveplan/queue-distribution
```
## Quick start
```ts
import {
LocalWorker,
WorkerManager,
WorkerPool,
} from "@suaveplan/queue-distribution";
const pool = new WorkerPool();
pool.addWorker(new LocalWorker({}, { id: "a", capacity: 4 }));
pool.addWorker(new LocalWorker({}, { id: "b", capacity: 4 }));
await pool.startAllWorkers();
const manager = new WorkerManager(pool, {
autoHealthCheck: false,
maxTaskRetries: 2,
});
const task = {
id: "double",
execute: async (n: number) => n * 2,
getStatus: () => "PENDING" as const,
setStatus: () => {},
getMetadata: () => ({ createdAt: new Date(), attempts: 0 }),
};
console.log(await manager.assignTask(task, 21)); // 42
```
## Modules
- [Task contract](./src/task/task.md) — `DistributedTask<I, O>`, `TaskStatus`, `TaskMetadata`.
- [Worker contract](./src/worker/worker.md) — `Worker`, `WorkerStatus`, `WorkerHealth`, `WorkerInfo` + Zod schemas.
- [AbstractWorker](./src/worker/abstract/abstract.md) — base class with lifecycle FSM, metrics, OTel emission.
- [`AbstractWorker` metrics helpers](./src/worker/abstract/abstract-metrics.md) — `WorkerMetricsState` accumulator.
- [LocalWorker](./src/worker/local/local.md) — in-process executor.
- [Strategy base](./src/load-balancing/base/base.md) — `LoadBalancingStrategy`, `AbstractLoadBalancingStrategy`.
- [RoundRobinStrategy](./src/load-balancing/round-robin/round-robin.md).
- [LeastBusyStrategy](./src/load-balancing/least-busy/least-busy.md) — optional EWMA performance bias.
- [WeightedStrategy](./src/load-balancing/weighted/weighted.md) — injectable `Rng`.
- [PeriodicHealthChecker](./src/health-checker/health-checker.md) — thresholds + cache + timeout.
- [WorkerPool](./src/pool/pool.md) — CRUD + criteria-based search.
- [WorkerManager](./src/manager/manager.md) — public dispatch surface.
- [WorkerManager dispatch](./src/manager/manager-dispatch.md) — bounded retry loop with @suaveplan/retry.
- [WorkerManager supervisor](./src/manager/manager-supervisor.md) — health-loop and restart logic.
- [Errors](./src/errors/queue-distribution-error.md) — `QueueDistributionError` + 12 stable codes.
- [Observability](./src/observability/instruments.md) — every counter, histogram, span the package emits.
- [Internal: NOOP_LOGGER](./src/internal/noop-logger.md).
## Design highlights
- 100% test coverage (statements + branches + functions + lines) under `provider: "istanbul"`.
- Injectable `Clock`, `IdGenerator`, `Rng`, `LoggerLike` everywhere — no `Math.random` / `Date.now` / `uuid` at module scope.
- `AbortSignal` threaded through every async public method.
- Retry routed through `@suaveplan/retry`; bounded loop, no recursion.
- Zod schemas at every public boundary (`WorkerHealthSchema`, `WorkerInfoSchema`, `TaskMetadataSchema`, …).
- Structured `SuaveplanError` subclasses with a frozen stable-code registry.
- Tree-shakeable via 15 per-feature subpath exports.
## Status
This package is part of the rebuild — version `0.1.0` while it stabilises. Graduation to `1.0.0` follows the criteria in [`CLAUDE.md`](../../../CLAUDE.md).