MCPcopy Index your code
hub / github.com/InfinitiBit/graphbit / execute_request_with_resilience

Method execute_request_with_resilience

python/src/llm/client.rs:1019–1120  ·  view source on GitHub ↗

Execute a single request with retry logic and circuit breaker

(
        provider: Arc<RwLock<Box<dyn LlmProviderTrait>>>,
        circuit_breaker: Arc<CircuitBreaker>,
        stats: Arc<RwLock<ClientStats>>,
        config: ClientConfig,
        request: LlmReq

Source from the content-addressed store, hash-verified

1017
1018 /// Execute a single request with retry logic and circuit breaker
1019 async fn execute_request_with_resilience(
1020 provider: Arc<RwLock<Box<dyn LlmProviderTrait>>>,
1021 circuit_breaker: Arc<CircuitBreaker>,
1022 stats: Arc<RwLock<ClientStats>>,
1023 config: ClientConfig,
1024 request: LlmRequest,
1025 ) -> Result<graphbit_core::llm::LlmResponse, PyErr> {
1026 let start_time = Instant::now();
1027
1028 // Update stats
1029 {
1030 let mut stats_guard = stats.write().await;
1031 stats_guard.total_requests += 1;
1032 }
1033
1034 // Check circuit breaker
1035 if !circuit_breaker.can_execute().await {
1036 return Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
1037 "Circuit breaker is open, request rejected",
1038 ));
1039 }
1040
1041 let mut last_error = None;
1042 let mut delay = config.base_retry_delay;
1043
1044 for attempt in 0..=config.max_retries {
1045 if config.debug {
1046 debug!("Executing LLM request (attempt {})", attempt + 1);
1047 }
1048
1049 let result = timeout(config.request_timeout, async {
1050 let guard = provider.read().await;
1051 guard.complete(request.clone()).await
1052 })
1053 .await;
1054
1055 match result {
1056 Ok(Ok(response)) => {
1057 // Success - update stats and circuit breaker
1058 let duration = start_time.elapsed();
1059
1060 {
1061 let mut stats_guard = stats.write().await;
1062 stats_guard.successful_requests += 1;
1063
1064 // Update average response time (simple moving average)
1065 let total_requests = stats_guard.total_requests as f64;
1066 stats_guard.average_response_time_ms =
1067 (stats_guard.average_response_time_ms * (total_requests - 1.0)
1068 + duration.as_millis() as f64)
1069 / total_requests;
1070 }
1071
1072 circuit_breaker.record_success().await;
1073 if config.debug {
1074 info!("LLM request completed successfully in {:?}", duration);
1075 }
1076

Callers

nothing calls this directly

Calls 7

to_py_errorFunction · 0.85
timeout_errorFunction · 0.85
can_executeMethod · 0.80
cloneMethod · 0.80
completeMethod · 0.45
record_successMethod · 0.45
record_failureMethod · 0.45

Tested by

no test coverage detected