# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
`do-over` is an async-first resilience and transient fault handling library for Rust, inspired by the .NET Polly library. It provides policies for retry, circuit breaker, timeout, bulkhead isolation, rate limiting, and hedging.
## Build Commands
```bash
# Build the project
cargo build
# Run all tests (unit + integration)
cargo test
# Run a specific test
cargo test test_name
# Run tests in a specific module
cargo test retry::
# Run benchmarks
cargo bench
# Run with specific features
cargo build --features "http metrics-prometheus metrics-otel"
# Run the HTTP service example
cargo run --example http_service
```
## Architecture
### Core Trait
All resilience policies implement the `Policy<E>` trait defined in `src/policy.rs`:
```rust
#[async_trait::async_trait]
pub trait Policy<E>: Send + Sync {
async fn execute<F, Fut, T>(&self, f: F) -> Result<T, E>
where
F: Fn() -> Fut + Send + Sync,
Fut: Future<Output = Result<T, E>> + Send,
T: Send;
}
```
### Error Type
`DoOverError<E>` in `src/error.rs` wraps application errors with policy-specific failures:
- `Timeout` - operation exceeded timeout
- `CircuitOpen` - circuit breaker is open
- `BulkheadFull` - bulkhead or rate limiter rejected
- `Inner(E)` - wrapped application error
### Policy Modules
| `src/retry.rs` | Fixed and exponential backoff retry |
| `src/circuit_breaker.rs` | Three-state circuit breaker (Closed → Open → Half-Open) |
| `src/timeout.rs` | Time-bounded operations |
| `src/bulkhead.rs` | Concurrency limiting with optional queue timeout |
| `src/rate_limit.rs` | Token bucket rate limiting |
| `src/hedge.rs` | Hedged requests for latency reduction |
| `src/wrap.rs` | Policy composition (outer wraps inner) |
### Policy Composition
Use `Wrap` to compose policies. Execution flows outer → inner → operation:
```rust
let policy = Wrap::new(
Bulkhead::new(10), // outermost: limit concurrency
Wrap::new(
CircuitBreaker::new(5, Duration::from_secs(60)),
Wrap::new(
RetryPolicy::exponential(3, Duration::from_millis(100), 2.0),
TimeoutPolicy::new(Duration::from_secs(5)) // innermost
)
)
);
```
Recommended ordering (outer to inner): Bulkhead → Circuit Breaker → Rate Limiter → Retry → Timeout
### Tower Integration
`src/tower.rs` provides `DoOverService<S, P>` for wrapping Tower services with any policy.
### Feature Flags
- `http` - Enables reqwest integration
- `metrics-prometheus` - Prometheus metrics
- `metrics-otel` - OpenTelemetry metrics
## Key Design Principles
- Uses `Result<T, E>` instead of exceptions
- All errors are explicit and typed
- No hidden retries or background behavior
- Async execution enforced at compile time (Tokio-based)
- Zero global state - all state contained in policy instances