mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
fix(analytics): retry implementation for forex crate call (#7280)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Sandeep Kumar <sandeep.kumar@juspay.in>
This commit is contained in:
@ -229,3 +229,6 @@ pub(crate) const PROTOCOL: &str = "ECv2";
|
||||
|
||||
/// Sender ID for Google Pay Decryption
|
||||
pub(crate) const SENDER_ID: &[u8] = b"Google";
|
||||
|
||||
/// Default value for the number of attempts to retry fetching forex rates
|
||||
pub const DEFAULT_ANALYTICS_FOREX_RETRY_ATTEMPTS: u64 = 3;
|
||||
|
||||
@ -2,11 +2,13 @@ use analytics::errors::AnalyticsError;
|
||||
use common_utils::errors::CustomResult;
|
||||
use currency_conversion::types::ExchangeRates;
|
||||
use error_stack::ResultExt;
|
||||
use router_env::logger;
|
||||
|
||||
use crate::{
|
||||
consts::DEFAULT_ANALYTICS_FOREX_RETRY_ATTEMPTS,
|
||||
core::errors::ApiErrorResponse,
|
||||
services::ApplicationResponse,
|
||||
utils::currency::{self, convert_currency, get_forex_rates},
|
||||
utils::currency::{self, convert_currency, get_forex_rates, ForexError as ForexCacheError},
|
||||
SessionState,
|
||||
};
|
||||
|
||||
@ -48,9 +50,45 @@ pub async fn get_forex_exchange_rates(
|
||||
state: SessionState,
|
||||
) -> CustomResult<ExchangeRates, AnalyticsError> {
|
||||
let forex_api = state.conf.forex_api.get_inner();
|
||||
let rates = get_forex_rates(&state, forex_api.data_expiration_delay_in_seconds)
|
||||
.await
|
||||
.change_context(AnalyticsError::ForexFetchFailed)?;
|
||||
let mut attempt = 1;
|
||||
|
||||
Ok((*rates.data).clone())
|
||||
logger::info!("Starting forex exchange rates fetch");
|
||||
loop {
|
||||
logger::info!("Attempting to fetch forex rates - Attempt {attempt} of {DEFAULT_ANALYTICS_FOREX_RETRY_ATTEMPTS}");
|
||||
|
||||
match get_forex_rates(&state, forex_api.data_expiration_delay_in_seconds).await {
|
||||
Ok(rates) => {
|
||||
logger::info!("Successfully fetched forex rates");
|
||||
return Ok((*rates.data).clone());
|
||||
}
|
||||
Err(error) => {
|
||||
let is_retryable = matches!(
|
||||
error.current_context(),
|
||||
ForexCacheError::CouldNotAcquireLock
|
||||
| ForexCacheError::EntryNotFound
|
||||
| ForexCacheError::ForexDataUnavailable
|
||||
| ForexCacheError::LocalReadError
|
||||
| ForexCacheError::LocalWriteError
|
||||
| ForexCacheError::RedisConnectionError
|
||||
| ForexCacheError::RedisLockReleaseFailed
|
||||
| ForexCacheError::RedisWriteError
|
||||
| ForexCacheError::WriteLockNotAcquired
|
||||
);
|
||||
|
||||
if !is_retryable {
|
||||
return Err(error.change_context(AnalyticsError::ForexFetchFailed));
|
||||
}
|
||||
|
||||
if attempt >= DEFAULT_ANALYTICS_FOREX_RETRY_ATTEMPTS {
|
||||
logger::error!("Failed to fetch forex rates after {DEFAULT_ANALYTICS_FOREX_RETRY_ATTEMPTS} attempts");
|
||||
return Err(error.change_context(AnalyticsError::ForexFetchFailed));
|
||||
}
|
||||
logger::warn!(
|
||||
"Forex rates fetch failed with retryable error, retrying in {attempt} seconds"
|
||||
);
|
||||
tokio::time::sleep(std::time::Duration::from_secs(attempt * 2)).await;
|
||||
attempt += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user