CircuitBreakerConfig

Struct CircuitBreakerConfig 

Source
pub struct CircuitBreakerConfig {
    pub failure_threshold: u32,
    pub recovery_timeout: Duration,
    pub success_threshold: u32,
    pub request_timeout: Duration,
}
Expand description

Configuration for circuit breaker behavior

Fields§

§failure_threshold: u32

Number of consecutive failures before opening the circuit

§recovery_timeout: Duration

Time to wait before attempting to close the circuit

§success_threshold: u32

Number of successful requests needed to close the circuit from half-open state

§request_timeout: Duration

Timeout for individual requests

Implementations§

Source§

impl CircuitBreakerConfig

Source

pub fn production() -> Self

Create a production-ready configuration

Source

pub fn development() -> Self

Create a development configuration with more lenient settings

Examples found in repository?
examples/resilience_example.rs (line 57)
55async fn demonstrate_circuit_breaker() -> Result<(), Box<dyn std::error::Error>> {
56    // Create a circuit breaker with development configuration
57    let config = CircuitBreakerConfig::development();
58    let breaker = CircuitBreaker::new(config);
59    
60    println!("Circuit Breaker State: {:?}", breaker.state());
61    println!("Failure Count: {}", breaker.failure_count());
62    println!("Success Rate: {:.2}%", breaker.success_rate());
63    
64    // Simulate some operations
65    for i in 1..=5 {
66        println!("  Operation {}: Circuit state = {:?}", i, breaker.state());
67        
68        // Simulate a failing operation
69        let result = breaker.call(async {
70            if i % 3 == 0 {
71                Err(ai_lib::types::AiLibError::NetworkError("Simulated network error".to_string()))
72            } else {
73                Ok(format!("Success {}", i))
74            }
75        }).await;
76        
77        match result {
78            Ok(response) => println!("    ✅ Success: {}", response),
79            Err(e) => println!("    ❌ Failed: {}", e),
80        }
81        
82        println!("    State: {:?}, Failures: {}", breaker.state(), breaker.failure_count());
83    }
84    
85    // Show final metrics
86    let metrics = breaker.get_metrics();
87    println!("Final Metrics:");
88    println!("  Total Requests: {}", metrics.total_requests);
89    println!("  Successful: {}", metrics.successful_requests);
90    println!("  Failed: {}", metrics.failed_requests);
91    println!("  Circuit Opens: {}", metrics.circuit_open_count);
92    
93    Ok(())
94}
95
96async fn demonstrate_rate_limiting() -> Result<(), Box<dyn std::error::Error>> {
97    // Create a rate limiter with conservative configuration
98    let config = RateLimiterConfig::conservative();
99    let rate_limiter = TokenBucket::new(config);
100    
101    println!("Rate Limiter Configuration:");
102    let metrics = rate_limiter.get_metrics();
103    println!("  Capacity: {}", metrics.capacity);
104    println!("  Refill Rate: {} req/s", metrics.refill_rate);
105    println!("  Adaptive: {}", metrics.is_adaptive);
106    println!("  Current Tokens: {}", metrics.current_tokens);
107    
108    // Simulate rapid requests
109    println!("\nSimulating rapid requests:");
110    for i in 1..=10 {
111        let start = std::time::Instant::now();
112        let result = rate_limiter.acquire(1).await;
113        let duration = start.elapsed();
114        
115        match result {
116            Ok(_) => println!("  Request {}: ✅ Acquired in {:?}", i, duration),
117            Err(e) => println!("  Request {}: ❌ Failed - {}", i, e),
118        }
119        
120        // Show current state
121        let metrics = rate_limiter.get_metrics();
122        println!("    Tokens: {}, Success Rate: {:.1}%", 
123                metrics.current_tokens, rate_limiter.success_rate());
124    }
125    
126    // Test adaptive rate adjustment
127    if metrics.is_adaptive {
128        println!("\nTesting adaptive rate adjustment:");
129        rate_limiter.adjust_rate(true);  // Success
130        rate_limiter.adjust_rate(false); // Failure
131        rate_limiter.adjust_rate(true);  // Success
132        
133        let metrics = rate_limiter.get_metrics();
134        println!("  Adaptive Rate: {:?}", metrics.adaptive_rate);
135    }
136    
137    Ok(())
138}
139
140async fn demonstrate_error_handling() -> Result<(), Box<dyn std::error::Error>> {
141    let error_manager = ErrorRecoveryManager::new();
142    
143    // Simulate different types of errors
144    let errors = vec![
145        ("Rate Limit", ai_lib::types::AiLibError::RateLimitExceeded("API rate limit exceeded".to_string())),
146        ("Network", ai_lib::types::AiLibError::NetworkError("Connection timeout".to_string())),
147        ("Authentication", ai_lib::types::AiLibError::AuthenticationError("Invalid API key".to_string())),
148        ("Context Length", ai_lib::types::AiLibError::ContextLengthExceeded("Request too long".to_string())),
149    ];
150    
151    println!("Error Handling and Pattern Analysis:");
152    for (error_type, error) in errors {
153        let context = ErrorContext::new("demo_provider".to_string(), "/demo/endpoint".to_string());
154        let result = error_manager.handle_error(&error, &context).await;
155        
156        println!("  {} Error: {}", error_type, error);
157        println!("    Suggested Action: {:?}", context.suggested_action);
158        println!("    Recovery Result: {}", if result.is_ok() { "Success" } else { "Failed" });
159    }
160    
161    // Show error statistics
162    let stats = error_manager.get_error_statistics();
163    println!("\nError Statistics:");
164    println!("  Total Errors: {}", stats.total_errors);
165    println!("  Unique Error Types: {}", stats.unique_error_types);
166    println!("  Most Common: {:?}", stats.most_common_error);
167    
168    // Show error patterns
169    let patterns = error_manager.get_error_patterns();
170    for (error_type, pattern) in patterns {
171        println!("  {:?}: {} occurrences, {:.2} errors/min", 
172                error_type, pattern.count, pattern.frequency);
173    }
174    
175    Ok(())
176}
177
178async fn demonstrate_integrated_resilience() -> Result<(), Box<dyn std::error::Error>> {
179    // Create all resilience components
180    let circuit_breaker = CircuitBreaker::new(CircuitBreakerConfig::development());
181    let rate_limiter = TokenBucket::new(RateLimiterConfig::development());
182    let error_manager = ErrorRecoveryManager::new();
183    
184    println!("Integrated Resilience Components:");
185    println!("  Circuit Breaker: {:?}", circuit_breaker.state());
186    println!("  Rate Limiter: {:.1}% success rate", rate_limiter.success_rate());
187    println!("  Error Manager: {} total errors", error_manager.get_error_statistics().total_errors);
188    
189    // Simulate a resilient operation
190    println!("\nSimulating resilient operation:");
191    for i in 1..=5 {
192        println!("  Operation {}:", i);
193        
194        // Step 1: Rate limiting
195        match rate_limiter.acquire(1).await {
196            Ok(_) => println!("    ✅ Rate limit passed"),
197            Err(e) => {
198                println!("    ❌ Rate limited: {}", e);
199                continue;
200            }
201        }
202        
203        // Step 2: Circuit breaker protection
204        let result = circuit_breaker.call(async {
205            // Simulate API call with occasional failures
206            if i % 4 == 0 {
207                Err(ai_lib::types::AiLibError::ProviderError("Simulated provider error".to_string()))
208            } else {
209                Ok(format!("API response {}", i))
210            }
211        }).await;
212        
213        // Step 3: Error handling
214        match result {
215            Ok(response) => {
216                println!("    ✅ Success: {}", response);
217                rate_limiter.adjust_rate(true);
218            }
219            Err(e) => {
220                println!("    ❌ Failed: {}", e);
221                rate_limiter.adjust_rate(false);
222                
223                // Convert CircuitBreakerError to AiLibError for error manager
224                let ai_error = match e {
225                    CircuitBreakerError::Underlying(err) => err,
226                    CircuitBreakerError::CircuitOpen(msg) => ai_lib::types::AiLibError::ProviderError(msg),
227                    CircuitBreakerError::RequestTimeout(msg) => ai_lib::types::AiLibError::TimeoutError(msg),
228                    CircuitBreakerError::Disabled => ai_lib::types::AiLibError::ConfigurationError("Circuit breaker disabled".to_string()),
229                };
230                
231                let context = ErrorContext::new("demo_provider".to_string(), "/demo/endpoint".to_string());
232                let _ = error_manager.handle_error(&ai_error, &context).await;
233            }
234        }
235        
236        // Show current state
237        println!("    State: CB={:?}, RL={:.1}%", 
238                circuit_breaker.state(), rate_limiter.success_rate());
239    }
240    
241    Ok(())
242}
Source

pub fn conservative() -> Self

Create a conservative configuration for critical systems

Examples found in repository?
examples/resilience_example.rs (line 271)
244async fn demonstrate_smart_configuration() -> Result<(), Box<dyn std::error::Error>> {
245    println!("Smart Configuration Options:");
246    
247    // 1. Smart defaults
248    println!("\n1. Smart Defaults:");
249    let _smart_client = AiClientBuilder::new(Provider::Groq)
250        .with_smart_defaults()
251        .build()?;
252    println!("  ✅ Client created with smart defaults");
253    
254    // 2. Production configuration
255    println!("\n2. Production Configuration:");
256    let _prod_client = AiClientBuilder::new(Provider::OpenAI)
257        .for_production()
258        .build()?;
259    println!("  ✅ Production client created");
260    
261    // 3. Development configuration
262    println!("\n3. Development Configuration:");
263    let _dev_client = AiClientBuilder::new(Provider::Gemini)
264        .for_development()
265        .build()?;
266    println!("  ✅ Development client created");
267    
268    // 4. Custom configuration
269    println!("\n4. Custom Configuration:");
270    let custom_config = ai_lib::config::ResilienceConfig {
271        circuit_breaker: Some(CircuitBreakerConfig::conservative()),
272        rate_limiter: Some(RateLimiterConfig::conservative()),
273        backpressure: Some(ai_lib::config::BackpressureConfig {
274            max_concurrent_requests: 10,
275        }),
276        error_handling: Some(ai_lib::config::ErrorHandlingConfig::default()),
277    };
278    
279    let _custom_client = AiClientBuilder::new(Provider::Mistral)
280        .with_resilience_config(custom_config)
281        .build()?;
282    println!("  ✅ Custom client created");
283    
284    println!("\nAll configuration options demonstrated successfully!");
285    Ok(())
286}

Trait Implementations§

Source§

impl Clone for CircuitBreakerConfig

Source§

fn clone(&self) -> CircuitBreakerConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CircuitBreakerConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CircuitBreakerConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for CircuitBreakerConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for CircuitBreakerConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,