From harness-claude
Implements circuit breaker pattern to protect services from cascading failures by blocking requests to failing dependencies until recovery. TypeScript/Node.js examples with opossum and fallbacks for external APIs.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Protect services from cascading failures by stopping requests to unhealthy dependencies until they recover
Prevents cascading failures in microservices using circuit breakers with closed/open/half-open states and fallbacks. Includes opossum Node.js/TypeScript example and manual implementation for slow/unavailable dependencies.
Implements circuit breaker patterns for fault tolerance, failure detection, and fallbacks. Use for external API calls, microservices, databases, and preventing cascading failures. Includes TypeScript, Node.js, Python, Java guides.
Assists implementing circuit breakers, retries, bulkheads, and resilience patterns for fault-tolerant distributed systems.
Share bugs, ideas, or general feedback.
Protect services from cascading failures by stopping requests to unhealthy dependencies until they recover
// services/circuit-breaker.ts — using opossum
import CircuitBreaker from 'opossum';
interface BreakerOptions {
timeout: number; // Max time for a single request (ms)
errorThresholdPercentage: number; // % of failures to trip
resetTimeout: number; // Time before trying again (ms)
volumeThreshold: number; // Minimum requests before evaluating threshold
}
const DEFAULT_OPTIONS: BreakerOptions = {
timeout: 5000,
errorThresholdPercentage: 50,
resetTimeout: 30000,
volumeThreshold: 10,
};
export function createBreaker<T>(
fn: (...args: any[]) => Promise<T>,
options: Partial<BreakerOptions> = {}
): CircuitBreaker {
const breaker = new CircuitBreaker(fn, { ...DEFAULT_OPTIONS, ...options });
breaker.on('open', () => console.warn(`Circuit opened for ${fn.name}`));
breaker.on('halfOpen', () => console.info(`Circuit half-open for ${fn.name}`));
breaker.on('close', () => console.info(`Circuit closed for ${fn.name}`));
return breaker;
}
// services/user-service.ts
import { createBreaker } from './circuit-breaker';
async function fetchUserFromAPI(userId: string): Promise<User> {
const res = await fetch(`https://api.example.com/users/${userId}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
const userBreaker = createBreaker(fetchUserFromAPI, {
timeout: 3000,
errorThresholdPercentage: 60,
resetTimeout: 15000,
});
// Fallback when circuit is open
userBreaker.fallback((userId: string) => ({
id: userId,
name: 'Unknown User',
cached: true,
}));
export async function getUser(userId: string): Promise<User> {
return userBreaker.fire(userId);
}
Manual implementation (no library):
class CircuitBreaker {
private state: 'closed' | 'open' | 'half-open' = 'closed';
private failures = 0;
private lastFailure = 0;
constructor(
private threshold: number = 5,
private resetTimeout: number = 30000
) {}
async execute<T>(fn: () => Promise<T>, fallback?: () => T): Promise<T> {
if (this.state === 'open') {
if (Date.now() - this.lastFailure > this.resetTimeout) {
this.state = 'half-open';
} else {
if (fallback) return fallback();
throw new Error('Circuit is open');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (err) {
this.onFailure();
if (fallback) return fallback();
throw err;
}
}
private onSuccess() {
this.failures = 0;
this.state = 'closed';
}
private onFailure() {
this.failures++;
this.lastFailure = Date.now();
if (this.failures >= this.threshold) this.state = 'open';
}
}
Libraries: opossum (most popular Node.js circuit breaker), cockatiel (modern, composable resilience policies), mollitia (middleware-based).
Tuning parameters:
Monitoring: Track circuit state changes, trip frequency, and open duration. A circuit that stays open indicates a persistent dependency failure. A circuit that oscillates indicates an unstable dependency.
https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker