From harness-claude
Implements the circuit breaker pattern to protect services from cascading failures. Wraps remote calls with failure tracking, automatic open/half-open/closed states, and fallback logic.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:resilience-circuit-breakerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Protect services from cascading failures by stopping requests to unhealthy dependencies until they recover
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
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudePrevent cascading failures in microservices with circuit breaker patterns: closed, open, half-open states, fail-fast logic, and fallback responses. Covers Node.js opossum library and manual implementation.
Assists implementing circuit breakers, retries, bulkheads, and resilience patterns for fault-tolerant distributed systems.
Provides patterns for managing external dependencies: circuit breakers, timeouts, retries with exponential backoff, bulkhead, graceful degradation, and dependency isolation. Use with any service or API call.