@octaviaflow/resilience
v0.1.0
Published
Cockatiel-based resilience primitives (timeout / retry / circuit-breaker / bulkhead / fallback) for Octaviaflow services
Maintainers
Readme
@octaviaflow/resilience
Cockatiel-based resilience primitives for Octaviaflow Bun services. Wraps
timeout, retry, circuit breaker, bulkhead, and fallback into a single
per-dependency policy with a drop-in resilientFetch.
Shipped via the Octaviaflow-System/ workspace alongside @octaviaflow/eventbus.
Install
bun add @octaviaflow/resilienceQuick start
import {
makePolicy,
resilientFetch,
attachObserver,
NonRetriable,
} from '@octaviaflow/resilience';
import { logger } from './config/logger';
import { meter } from './instrumentation';
// One singleton per remote dependency
const enginePolicy = makePolicy({
name: 'engine',
timeoutMs: 5_000,
retry: { attempts: 3, initialDelayMs: 100, maxDelayMs: 1_000 },
breaker: { threshold: 5, durationMs: 30_000 },
bulkhead: { maxConcurrent: 50, maxQueue: 100 },
});
attachObserver(enginePolicy, { logger, meter });
export const engineFetch = resilientFetch(enginePolicy);
// Call site change is exactly: fetch(...) → engineFetch(...)
const res = await engineFetch(`${ENGINE_URL}/api/v1/engine/execute`, {
method: 'POST',
body: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' },
});Fallback at call sites
import { BrokenCircuitError, TaskCancelledError } from 'cockatiel';
import { NonRetriable } from '@octaviaflow/resilience';
try {
const res = await trqeFetch(`/token/${id}`);
return await res.json();
} catch (err) {
if (err instanceof BrokenCircuitError || err instanceof TaskCancelledError) {
const cached = await readCachedToken(id);
if (cached) return cached;
}
throw err;
}Allowed fallback strategies, in preference order:
- Serve cached value (Valkey / in-memory LRU).
- Serve degraded response (e.g. flag the run as
pendingAuthRefresh). - Reject with
503 Service Unavailableand aRetry-Afterheader.
Returning 200 OK with stale or partial data without explicit caller opt-in
is forbidden.
Per-dependency policy matrix
The values consumed by every Octaviaflow service are normative — see
Octaviaflow-Docs/Infrastructure/resilience/octaviaflow-resilience-package.md
section 5.4.
Tests
bun test # unit (no infra)
bun run test:integration # against a Bun.serve fixture in-processReferences
- ADR:
Octaviaflow-Docs/Decisions/adr-resilience-cockatiel.md - Implementation spec:
Octaviaflow-Docs/Infrastructure/resilience/octaviaflow-resilience-package.md - Cockatiel: https://github.com/connor4312/cockatiel
