@setu-ts/resilience-plugin — protect calls to unreliable services
Add it: setu add resilience adds it and wires ResiliencePlugin() in a recognized functional
config. It provides CAPABILITIES.RESILIENCE (IResilienceService).
Retry and limit an upstream HTTP call
Keep one wrapped callable across requests; initialize it when services become available:
import { CAPABILITIES } from '@setu-ts/common';
import type { HardenedCall, IResilienceService, IRouterApi } from '@setu-ts/common';
export function registerBillingRoutes(router: IRouterApi): void {
let billing: HardenedCall<string> | undefined;
router.get('/billing-status', {
handler: async (ctx) => {
billing ??= ctx.services.get<IResilienceService>(CAPABILITIES.RESILIENCE).wrap(
async (signal) => {
const response = await fetch('https://billing.example.com/status', { signal });
if (!response.ok) throw new Error('Billing failed');
return await response.text();
},
{
retry: { limit: 3, delay: 100, backoff: 'exponential' },
circuitBreaker: { threshold: 5, timeout: 10000, resetTimeout: 30000 },
timeout: 2000, bulkhead: { maxConcurrent: 8 },
},
);
return ctx.response.text(await billing(ctx.signal));
},
});
}
Behaviour the types do not show
- Layers execute bulkhead, circuit breaker, retry, timeout, then the supplied function.
- Breaker and bulkhead state live per
wrapcall. Creating a wrapper on every request discards their shared state; retain the callable as above. retry.limitcounts total attempts;1means no retry. Delays, breaker windows, cooldowns and timeouts are milliseconds. Timeout applies separately to each attempt.- Timeout aborts the attempt’s signal. Forward it to the underlying I/O to cancel that work; ignoring it only rejects the caller’s wait. A caller signal cancels the whole chain.
- A full bulkhead rejects after its queue fills; omitted
maxQueuemeans no waiting queue.
Other options
retry: true,circuitBreaker: trueandbulkhead: truerequire matchingdefaultRetry,defaultCircuitBreakeranddefaultBulkheadpolicies onResiliencePlugin.- Omitted or
falsepolicy layers are disabled; an explicit object overrides the default. TimeoutError,BulkheadFullErrorandCircuitOpenErrorcarry HTTP hints 504, 503 and 503.