use crate::Error;
pub const DEFAULT_MAX_RETRIES: u32 = 3;
#[cfg(feature = "sync")]
mod sync_retry {
use super::*;
pub fn retry_on_connection_reset_with_limit<T, F>(mut operation: F, max_retries: u32) -> Result<T, Error>
where
F: FnMut() -> Result<T, Error>,
{
let mut attempts = 0;
loop {
match operation() {
Err(Error::ConnectionReset) if attempts < max_retries => {
attempts += 1;
continue;
}
other => return other,
}
}
}
pub fn retry_on_connection_reset<T, F>(operation: F) -> Result<T, Error>
where
F: FnMut() -> Result<T, Error>,
{
retry_on_connection_reset_with_limit(operation, DEFAULT_MAX_RETRIES)
}
}
#[cfg(feature = "async")]
mod async_retry {
use super::*;
use futures::Future;
pub async fn retry_on_connection_reset_with_limit<T, F, Fut>(mut operation: F, max_retries: u32) -> Result<T, Error>
where
F: FnMut() -> Fut,
Fut: Future<Output = Result<T, Error>>,
{
let mut attempts = 0;
loop {
match operation().await {
Err(Error::ConnectionReset) if attempts < max_retries => {
attempts += 1;
continue;
}
other => return other,
}
}
}
pub async fn retry_on_connection_reset<T, F, Fut>(operation: F) -> Result<T, Error>
where
F: FnMut() -> Fut,
Fut: Future<Output = Result<T, Error>>,
{
retry_on_connection_reset_with_limit(operation, DEFAULT_MAX_RETRIES).await
}
}
#[cfg(feature = "sync")]
pub mod blocking {
pub(crate) use super::sync_retry::*;
}
#[cfg(all(feature = "sync", not(feature = "async")))]
#[allow(unused_imports)]
pub use sync_retry::*;
#[cfg(feature = "async")]
pub use async_retry::*;
#[cfg(test)]
#[path = "retry_tests.rs"]
mod tests;