use ant_evm::PaymentQuote;
use ant_protocol::{NetworkAddress, PrettyPrintRecordKey};
use super::{Network, RetryStrategy};
use super::{NetworkError, PeerInfo, Record, Strategy};
use tokio::time::sleep;
impl Network {
pub async fn put_record_with_retries(
&self,
record: Record,
to: Vec<PeerInfo>,
strategy: &Strategy,
) -> Result<(), NetworkError> {
let addr = PrettyPrintRecordKey::from(&record.key).into_owned();
let mut errors = vec![];
for duration in strategy.put_retry.backoff() {
match self
.put_record(record.clone(), to.clone(), strategy.put_quorum)
.await
{
Ok(()) => return Ok(()),
Err(err) if err.cannot_retry() => {
return Err(err);
}
Err(err) => {
warn!("Put record failed at {addr}: {err:?}, retrying in {duration:?}");
errors.push(err.clone());
match duration {
Some(retry_delay) => sleep(retry_delay).await,
None => return Err(err),
}
}
}
}
Err(NetworkError::InvalidRetryStrategy)
}
pub async fn get_record_with_retries(
&self,
addr: NetworkAddress,
strategy: &Strategy,
) -> Result<Option<Record>, NetworkError> {
let mut errors = vec![];
let quorum = strategy.get_quorum;
for duration in strategy.get_retry.backoff() {
match self.get_record(addr.clone(), quorum).await {
Ok(Some(record)) => return Ok(Some(record)),
Err(err) if matches!(err, NetworkError::SplitRecord(_)) => {
return Err(err);
}
Err(err) if err.cannot_retry() => {
return Err(err);
}
Ok(None) => {
warn!("Record not found at {addr}, retrying in {duration:?}");
match duration {
Some(retry_delay) => sleep(retry_delay).await,
None => return Ok(None),
}
}
Err(err) => {
warn!("Get record failed at {addr}: {err:?}, retrying in {duration:?}");
errors.push(err.clone());
match duration {
Some(retry_delay) => sleep(retry_delay).await,
None => return Err(err),
}
}
}
}
Err(NetworkError::InvalidRetryStrategy)
}
pub async fn get_quotes_with_retries(
&self,
addr: NetworkAddress,
data_type: u32,
data_size: usize,
) -> Result<Option<Vec<(PeerInfo, PaymentQuote)>>, NetworkError> {
let mut errors = vec![];
for duration in RetryStrategy::Once.backoff() {
match self.get_quotes(addr.clone(), data_type, data_size).await {
Ok(quotes) => return Ok(quotes),
Err(err) if err.cannot_retry() => {
return Err(err);
}
Err(err) => {
warn!("Get quotes failed at {addr}: {err:?}, retrying in {duration:?}");
errors.push(err.clone());
match duration {
Some(retry_delay) => sleep(retry_delay).await,
None => return Err(err),
}
}
}
}
Err(NetworkError::InvalidRetryStrategy)
}
pub async fn get_closest_peers_with_retries(
&self,
addr: NetworkAddress,
count: Option<usize>,
) -> Result<Vec<PeerInfo>, NetworkError> {
let mut errors = vec![];
for duration in RetryStrategy::Once.backoff() {
match self.get_closest_peers(addr.clone(), count).await {
Ok(peers) => return Ok(peers),
Err(err) if err.cannot_retry() => {
return Err(err);
}
Err(err) => {
warn!("Get closest peers failed at {addr}: {err:?}, retrying in {duration:?}");
errors.push(err.clone());
match duration {
Some(retry_delay) => sleep(retry_delay).await,
None => return Err(err),
}
}
}
}
Err(NetworkError::InvalidRetryStrategy)
}
}