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,68 @@
# CircuitBreakerRegistry
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Owns one `MeshCircuitBreaker` per relay path and exposes a thin facade for cross-path queries (`listOpenPaths`, `getState(pathId)`). Centralising the breakers means there's exactly one place that decides "is this path healthy?" and middleware/probes can both consult it without state-sharing.
## Features
- Lazy construction: `getOrCreate` makes a breaker on first reference, returns the existing instance on subsequent calls.
- Per-call config overrides on `getOrCreate` so different paths can have different thresholds.
- Shared `defaults` config applied to every breaker that doesn't override.
- `listOpenPaths()` for observability dashboards / health endpoints.
- `remove(pathId)` for explicit teardown when a peer leaves the mesh.
## Usage: Basic Example
```ts
import { CircuitBreakerRegistry } from "@suaveplan/network-plugin-circuit-breaker";
const registry = new CircuitBreakerRegistry();
const cb = registry.getOrCreate("meshA:host1→meshB:host2");
if (cb.canExecute()) {
/* ... */
}
```
## Usage: Advanced Example
```ts
import { CircuitBreakerRegistry } from "@suaveplan/network-plugin-circuit-breaker";
const registry = new CircuitBreakerRegistry({
defaults: {
failureThreshold: 3,
successThreshold: 2,
openDurationMs: 10_000,
halfOpenMaxCalls: 2,
},
});
// per-path override for a known-flaky link
registry.getOrCreate("meshA:host1→meshC:host5", {
failureThreshold: 10,
});
const open = registry.listOpenPaths();
if (open.length > 0) {
metrics.gauge("mesh.open_breakers", open.length);
}
```
## API Reference
- `interface CircuitBreakerRegistryOptions { defaults? }`.
- `getOrCreate(pathId, options?): MeshCircuitBreaker`.
- `getState(pathId): CircuitBreakerState | undefined`.
- `remove(pathId): boolean`.
- `listOpenPaths(): readonly string[]`.
- `paths(): readonly string[]` — every known path id, regardless of state.
- `size(): number`.
- `clear()`.
## Implementation Notes
`getOrCreate` is the canonical constructor — the registry never returns a raw `new` breaker, so observers don't have to wonder whether they're looking at a registry-owned or one-off instance. Per-call options shallow-merge over `defaults`, with caller options winning. `listOpenPaths` consults `getState()` (not the cached state) so paths that have lazy-transitioned to `HALF_OPEN` are excluded from the open list — matching what callers expect from "which paths are dead right now?". The companion `paths()` accessor returns every known path so probe loops can re-query each one's live state without missing entries that have already moved to `HALF_OPEN`. This split keeps health-dashboard semantics ("just the dead ones") separate from probe-driver semantics ("everything we might want to retry").