@@ -5,21 +5,39 @@ use std::time::Duration;
55use tokio:: time:: sleep;
66use url:: Url ;
77
8- /// Send an HTTP request with retry logic for transient failures.
9- ///
10- /// Retries up to 2 times on retryable status codes (429, 5xx) or connection errors,
11- /// with linear backoff starting at 250ms.
12- pub async fn send_with_retry < F > (
8+ /// Default retry parameters.
9+ const DEFAULT_MAX_RETRIES : usize = 2 ;
10+ const DEFAULT_BASE_DELAY_MS : u64 = 250 ;
11+
12+ /// Configurable retry parameters for LLM adapter requests.
13+ #[ derive( Debug , Clone ) ]
14+ pub struct RetryConfig {
15+ pub max_retries : usize ,
16+ pub base_delay_ms : u64 ,
17+ }
18+
19+ impl Default for RetryConfig {
20+ fn default ( ) -> Self {
21+ Self {
22+ max_retries : DEFAULT_MAX_RETRIES ,
23+ base_delay_ms : DEFAULT_BASE_DELAY_MS ,
24+ }
25+ }
26+ }
27+
28+ /// Send an HTTP request with configurable retry parameters.
29+ pub async fn send_with_retry_config < F > (
1330 adapter_name : & str ,
14- mut make_request : F ,
31+ retry_config : & RetryConfig ,
32+ make_request : & mut F ,
1533) -> Result < reqwest:: Response >
1634where
1735 F : FnMut ( ) -> reqwest:: RequestBuilder ,
1836{
19- const MAX_RETRIES : usize = 2 ;
20- const BASE_DELAY_MS : u64 = 250 ;
37+ let max_retries = retry_config . max_retries ;
38+ let base_delay_ms = retry_config . base_delay_ms ;
2139
22- for attempt in 0 ..=MAX_RETRIES {
40+ for attempt in 0 ..=max_retries {
2341 match make_request ( ) . send ( ) . await {
2442 Ok ( response) => {
2543 if response. status ( ) . is_success ( ) {
2846
2947 let status = response. status ( ) ;
3048 let body = response. text ( ) . await . unwrap_or_default ( ) ;
31- if is_retryable_status ( status) && attempt < MAX_RETRIES {
32- sleep ( Duration :: from_millis ( BASE_DELAY_MS * ( attempt as u64 + 1 ) ) ) . await ;
49+ if is_retryable_status ( status) && attempt < max_retries {
50+ sleep ( Duration :: from_millis ( base_delay_ms * ( attempt as u64 + 1 ) ) ) . await ;
3351 continue ;
3452 }
3553
4361 ) ;
4462 }
4563 Err ( err) => {
46- if attempt < MAX_RETRIES {
47- sleep ( Duration :: from_millis ( BASE_DELAY_MS * ( attempt as u64 + 1 ) ) ) . await ;
64+ if attempt < max_retries {
65+ sleep ( Duration :: from_millis ( base_delay_ms * ( attempt as u64 + 1 ) ) ) . await ;
4866 continue ;
4967 }
5068 return Err ( err. into ( ) ) ;
0 commit comments