first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
# `Worker` contract
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
- [abstract-metrics](./abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_ - [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./worker.md) — <!-- begin:auto-docs --> _(no submodules)_- abstract-metrics — `abstract-metrics.ts` carries the…
- [abstract-metrics](./abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./worker.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract-metrics](./abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./worker.md) — <!-- begin:auto-docs --> _(no submodules)_- abstract-metrics — `abstract…
- [abstract-metrics](./abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./worker.md) — <!-- begin:auto-docs --> _(no submodules)_- abstract-metrics — `abstract-metrics.ts` carries th…
- [abstract-metrics](./abstract/abstract-metrics.md) — `abstract-metrics.ts` carries the pure functions and the small accumulator used by `AbstractWorker` to track success/fa…
- [abstract](./abstract/abstract.md) — <!-- begin:auto-docs --> _(no submodules)_- [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_ - [local](./local/local.md) — <!-- begin:auto-docs --> _(no submodules)_- [worker](./worker.md) — <!-- begin:auto-docs --> _(no submodules)_
## Purpose
`Worker` is the structural interface every distribution-tier executor implements. It describes lifecycle (`start`, `stop`), task execution (`executeTask`), health probing (`getHealth`, `canAcceptTask`), and introspection (`getInfo`). Concrete workers (`LocalWorker`, `RemoteWorker` from the HTTP plugin, `WorkerThreadWorker` from the worker-thread plugin) extend `AbstractWorker`, but downstream code should program against `Worker` so transport choices stay swappable.
## Features
- `id`, `capacity`, `weight`, `status: WorkerStatusValue`, `activeTasks` fields kept in sync by the worker base class.
- `executeTask<I, O>(task, input, signal?): Promise<O>` — preserves caller's `<I, O>` generics end-to-end.
- `getHealth(signal?): Promise<WorkerHealth>` — pluggable health probe; the abstract base returns synthesised metrics, subclasses override with real measurements.
- `start(signal?)`, `stop(force?, signal?)` — idempotent lifecycle.
- `canAcceptTask(): boolean` — used by load-balancing strategies to filter the candidate pool.
- `getInfo(): WorkerInfo` — snapshot of identity, type, capacity, weight, status, active count, optional `startedAt` / `lastHealthCheck` / `lastHealthStatus` / `capabilities`.
- `WorkerStatusSchema`, `WorkerHealthSchema`, `WorkerInfoSchema` — Zod schemas at every public boundary.
## Usage: Basic Example
```ts
import {
type Worker,
WorkerStatus,
WorkerHealthSchema,
} from "@suaveplan/queue-distribution/worker/worker";
function printWorker(worker: Worker): void {
const info = worker.getInfo();
console.log(`${info.type}/${info.id} — ${info.status}, ${info.activeTasks}/${info.capacity}`);
}
async function probeHealth(worker: Worker): Promise<boolean> {
const health = await worker.getHealth();
WorkerHealthSchema.parse(health); // validate at the boundary
return health.isHealthy && worker.status !== WorkerStatus.UNHEALTHY;
}
```
## Usage: Advanced Example
Workers can carry arbitrary capabilities — exposed via `getInfo().capabilities` — that strategies and supervisors inspect to make routing decisions.
```ts
import {
type Worker,
WorkerInfoSchema,
} from "@suaveplan/queue-distribution/worker/worker";
function findGpuWorkers(workers: readonly Worker[]): Worker[] {
return workers.filter((worker) => {
const info = WorkerInfoSchema.parse(worker.getInfo());
return info.capabilities?.gpu === true && info.status === "ONLINE";
});
}
```
## API Reference
- `interface Worker` — fields and methods above.
- `const WorkerStatus` — frozen literal map (`ONLINE` / `BUSY` / `OFFLINE` / `UNHEALTHY`).
- `type WorkerStatusValue` — union of the four states.
- `const WorkerStatusSchema: z.ZodEnum` — accepts only the four states.
- `interface WorkerHealth` — `isHealthy: boolean` + `WorkerHealthMetrics`.
- `interface WorkerHealthMetrics` — `cpu`, `memory`, `tasksFailed`, `tasksSucceeded`, `responseTime`, indexed extras.
- `const WorkerHealthSchema: z.ZodType<WorkerHealth>`.
- `interface WorkerInfo` — identity + capacity + weight + status + active count + optional timestamps + optional health snapshot + optional capabilities map.
- `const WorkerInfoSchema: z.ZodType<WorkerInfo>` — `capacity` must be a positive integer; `weight` non-negative; `activeTasks` non-negative integer.
## Implementation Notes
The interface mutates the worker's `status` and `activeTasks` fields directly rather than threading them through accessors because the `AbstractWorker` base maintains them as the source of truth, and load-balancing strategies access them in hot paths where allocator pressure matters. `getInfo()` returns a fresh structural snapshot every call — callers must not mutate it. Schemas exist so transport-specific subclasses (e.g. a deserialised remote worker payload) can validate the shape they construct before publishing it to the pool.