resilience-patterns by claude-dev-suite/claude-dev-suite
npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill resilience-patternsasync function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
baseDelay = 1000,
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries) throw error;
if (!isRetryable(error)) throw error;
const delay = baseDelay * Math.pow(2, attempt) + Math.random() * 1000;
await new Promise((r) => setTimeout(r, delay));
}
}
throw new Error('Unreachable');
}
function isRetryable(error: unknown): boolean {
if (error instanceof Error && 'status' in error) {
const status = (error as { status: number }).status;
return status === 429 || status >= 500;
}
return true;
}
class CircuitBreaker {
private failures = 0;
private lastFailure = 0;
private state: 'closed' | 'open' | 'half-open' = 'closed';
constructor(
private threshold = 5,
private resetTimeout = 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 breaker is open');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
if (fallback) return fallback();
throw error;
}
}
private onSuccess() { this.failures = 0; this.state = 'closed'; }
private onFailure() {
this.failures++;
this.lastFailure = Date.now();
if (this.failures >= this.threshold) this.state = 'open';
}
}
// Usage
const breaker = new CircuitBreaker(5, 30000);
const result = await breaker.execute(
() => externalApi.call(),
() => cachedResult, // fallback
);
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
baseDelay = 1000,
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries) throw error;
if (!isRetryable(error)) throw error;
const delay = baseDelay * Math.pow(2, attempt) + Math.random() * 1000;
await new Promise((r) => setTimeout(r, delay));
}
}
throw new Error('Unreachable');
}
function isRetryable(error: unknown): boolean {
if (error instanceof Error && 'status' in error) {
const status = (error as { status: number }).status;
return status === 429 || status >= 500;
}
return true;
}
class CircuitBreaker {
private failures = 0;
private lastFailure = 0;
private state: 'closed' | 'open' | 'half-open' = 'closed';
constructor(
private threshold = 5,
private resetTimeout = 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 breaker is open');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
if (fallback) return fallback();
throw error;
}
}
private onSuccess() { this.failures = 0; this.state = 'closed'; }
private onFailure() {
this.failures++;
this.lastFailure = Date.now();
if (this.failures >= this.threshold) this.state = 'open';
}
}
// Usage
const breaker = new CircuitBreaker(5, 30000);
const result = await breaker.execute(
() => externalApi.call(),
() => cachedResult, // fallback
);
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
@CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback")
@Retry(name = "paymentService")
@TimeLimiter(name = "paymentService")
public CompletableFuture<Payment> processPayment(Order order) {
return CompletableFuture.supplyAsync(() -> paymentClient.charge(order));
}
public CompletableFuture<Payment> paymentFallback(Order order, Throwable t) {
return CompletableFuture.completedFuture(Payment.pending(order.getId()));
}
# application.yml
resilience4j:
circuitbreaker:
instances:
paymentService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 30s
retry:
instances:
paymentService:
maxAttempts: 3
waitDuration: 1s
exponentialBackoffMultiplier: 2
async function withTimeout<T>(fn: () => Promise<T>, ms: number): Promise<T> {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), ms);
try {
return await fn();
} finally {
clearTimeout(timer);
}
}
| 模式 | 适用场景 |
|---|---|
| 重试 | 暂时性故障(网络问题、5xx错误、429限流) |
| 熔断器 | 同一依赖项重复故障 |
| 超时 | 防止连接挂起 |
| 舱壁隔离 | 按依赖项隔离资源池 |
| 降级 | 服务降级但仍可用 |
| 反模式 | 修复方法 |
|---|---|
| 重试非幂等操作 | 仅重试幂等请求(GET、相同键的PUT) |
| 重试延迟无抖动 | 添加随机抖动防止惊群效应 |
| 每个请求单独使用熔断器(而非按服务) | 对同一服务的请求共享熔断器实例 |
| 熔断器开启时无降级方案 | 提供缓存/降级响应 |
| 重试400错误 | 仅重试暂时性错误(429、5xx、网络问题) |
每周安装量
1
代码仓库
首次出现
3天前
安全审计
安装于
amp1
cline1
openclaw1
opencode1
cursor1
kimi-cli1
@CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback")
@Retry(name = "paymentService")
@TimeLimiter(name = "paymentService")
public CompletableFuture<Payment> processPayment(Order order) {
return CompletableFuture.supplyAsync(() -> paymentClient.charge(order));
}
public CompletableFuture<Payment> paymentFallback(Order order, Throwable t) {
return CompletableFuture.completedFuture(Payment.pending(order.getId()));
}
# application.yml
resilience4j:
circuitbreaker:
instances:
paymentService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 30s
retry:
instances:
paymentService:
maxAttempts: 3
waitDuration: 1s
exponentialBackoffMultiplier: 2
async function withTimeout<T>(fn: () => Promise<T>, ms: number): Promise<T> {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), ms);
try {
return await fn();
} finally {
clearTimeout(timer);
}
}
| Pattern | Use When |
|---|---|
| Retry | Transient failures (network, 5xx, 429) |
| Circuit breaker | Repeated failures to same dependency |
| Timeout | Preventing hung connections |
| Bulkhead | Isolating resource pools per dependency |
| Fallback | Degraded but available service |
| Anti-Pattern | Fix |
|---|---|
| Retrying non-idempotent operations | Only retry idempotent requests (GET, PUT with same key) |
| No jitter on retry delay | Add random jitter to prevent thundering herd |
| Circuit breaker per request (not per service) | Share breaker instance across requests to same service |
| No fallback for open circuit | Provide cached/degraded response |
| Retrying 400 errors | Only retry transient errors (429, 5xx, network) |
Weekly Installs
1
Repository
First Seen
3 days ago
Security Audits
Installed on
amp1
cline1
openclaw1
opencode1
cursor1
kimi-cli1
Azure 升级评估与自动化工具 - 轻松迁移 Functions 计划、托管层级和 SKU
79,900 周安装
Docnify自动化:通过Rube MCP和Composio工具包实现文档操作自动化
1 周安装
Docmosis自动化集成指南:通过Rube MCP与Composio实现文档生成自动化
1 周安装
Dictionary API自动化教程:通过Rube MCP和Composio实现词典API操作自动化
1 周安装
detrack-automation:自动化追踪技能,集成Claude AI提升开发效率
1 周安装
Demio自动化工具包:通过Rube MCP和Composio实现Demio操作自动化
1 周安装
Deel自动化工具:通过Rube MCP与Composio实现HR与薪资操作自动化
1 周安装