diff --git a/crates/external_services/src/grpc_client.rs b/crates/external_services/src/grpc_client.rs index 5a9bd6143d..1b93ac6bd8 100644 --- a/crates/external_services/src/grpc_client.rs +++ b/crates/external_services/src/grpc_client.rs @@ -35,7 +35,7 @@ pub type Client = hyper_util::client::legacy::Client; pub struct GrpcClients { /// The routing client #[cfg(feature = "dynamic_routing")] - pub dynamic_routing: RoutingStrategy, + pub dynamic_routing: Option, /// Health Check client for all gRPC services #[cfg(feature = "dynamic_routing")] pub health_client: HealthCheckClient, @@ -47,7 +47,7 @@ pub struct GrpcClients { pub struct GrpcClientSettings { #[cfg(feature = "dynamic_routing")] /// Configs for Dynamic Routing Client - pub dynamic_routing_client: DynamicRoutingClientConfig, + pub dynamic_routing_client: Option, /// Configs for Unified Connector Service client pub unified_connector_service: Option, } @@ -69,9 +69,10 @@ impl GrpcClientSettings { let dynamic_routing_connection = self .dynamic_routing_client .clone() - .get_dynamic_routing_connection(client.clone()) - .await - .expect("Failed to establish a connection with the Dynamic Routing Server"); + .map(|config| config.get_dynamic_routing_connection(client.clone())) + .transpose() + .expect("Failed to establish a connection with the Dynamic Routing Server") + .flatten(); #[cfg(feature = "dynamic_routing")] let health_client = HealthCheckClient::build_connections(self, client) diff --git a/crates/external_services/src/grpc_client/dynamic_routing.rs b/crates/external_services/src/grpc_client/dynamic_routing.rs index a9ee7852d3..f4aeec7655 100644 --- a/crates/external_services/src/grpc_client/dynamic_routing.rs +++ b/crates/external_services/src/grpc_client/dynamic_routing.rs @@ -47,11 +47,11 @@ pub enum DynamicRoutingError { #[derive(Debug, Clone)] pub struct RoutingStrategy { /// success rate service for Dynamic Routing - pub success_rate_client: Option>, + pub success_rate_client: SuccessRateCalculatorClient, /// contract based routing service for Dynamic Routing - pub contract_based_client: Option>, + pub contract_based_client: ContractScoreCalculatorClient, /// elimination service for Dynamic Routing - pub elimination_based_client: Option>, + pub elimination_based_client: EliminationAnalyserClient, } /// Contains the Dynamic Routing Client Config @@ -74,32 +74,28 @@ pub enum DynamicRoutingClientConfig { impl DynamicRoutingClientConfig { /// establish connection with the server - pub async fn get_dynamic_routing_connection( + pub fn get_dynamic_routing_connection( self, client: Client, - ) -> Result> { - let (success_rate_client, contract_based_client, elimination_based_client) = match self { + ) -> Result, Box> { + match self { Self::Enabled { host, port, .. } => { let uri = format!("http://{host}:{port}").parse::()?; logger::info!("Connection established with dynamic routing gRPC Server"); - ( - Some(SuccessRateCalculatorClient::with_origin( - client.clone(), - uri.clone(), - )), - Some(ContractScoreCalculatorClient::with_origin( - client.clone(), - uri.clone(), - )), - Some(EliminationAnalyserClient::with_origin(client, uri)), - ) + + let (success_rate_client, contract_based_client, elimination_based_client) = ( + SuccessRateCalculatorClient::with_origin(client.clone(), uri.clone()), + ContractScoreCalculatorClient::with_origin(client.clone(), uri.clone()), + EliminationAnalyserClient::with_origin(client, uri), + ); + + Ok(Some(RoutingStrategy { + success_rate_client, + contract_based_client, + elimination_based_client, + })) } - Self::Disabled => (None, None, None), - }; - Ok(RoutingStrategy { - success_rate_client, - contract_based_client, - elimination_based_client, - }) + Self::Disabled => Ok(None), + } } } diff --git a/crates/external_services/src/grpc_client/health_check_client.rs b/crates/external_services/src/grpc_client/health_check_client.rs index 94d78df795..e0dac3a8fb 100644 --- a/crates/external_services/src/grpc_client/health_check_client.rs +++ b/crates/external_services/src/grpc_client/health_check_client.rs @@ -53,11 +53,11 @@ impl HealthCheckClient { ) -> Result> { let dynamic_routing_config = &config.dynamic_routing_client; let connection = match dynamic_routing_config { - DynamicRoutingClientConfig::Enabled { + Some(DynamicRoutingClientConfig::Enabled { host, port, service, - } => Some((host.clone(), *port, service.clone())), + }) => Some((host.clone(), *port, service.clone())), _ => None, }; @@ -81,11 +81,11 @@ impl HealthCheckClient { ) -> HealthCheckResult { let dynamic_routing_config = &config.dynamic_routing_client; let connection = match dynamic_routing_config { - DynamicRoutingClientConfig::Enabled { + Some(DynamicRoutingClientConfig::Enabled { host, port, service, - } => Some((host.clone(), *port, service.clone())), + }) => Some((host.clone(), *port, service.clone())), _ => None, }; diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs index 7feea3286c..87ed5ff40a 100644 --- a/crates/router/src/core/payments/routing.rs +++ b/crates/router/src/core/payments/routing.rs @@ -2100,13 +2100,13 @@ where "performing success_based_routing for profile {}", profile_id.get_string_repr() ); - let client = state + let client = &state .grpc_client .dynamic_routing - .success_rate_client .as_ref() .ok_or(errors::RoutingError::SuccessRateClientInitializationError) - .attach_printable("success_rate gRPC client not found")?; + .attach_printable("dynamic routing gRPC client not found")? + .success_rate_client; let success_based_routing_configs = routing::helpers::fetch_dynamic_routing_configs::< api_routing::SuccessBasedRoutingConfig, @@ -2284,13 +2284,13 @@ pub async fn perform_elimination_routing( "performing elimination_routing for profile {}", profile_id.get_string_repr() ); - let client = state + let client = &state .grpc_client .dynamic_routing - .elimination_based_client .as_ref() .ok_or(errors::RoutingError::EliminationClientInitializationError) - .attach_printable("elimination routing's gRPC client not found")?; + .attach_printable("dynamic routing gRPC client not found")? + .elimination_based_client; let elimination_routing_config = routing::helpers::fetch_dynamic_routing_configs::< api_routing::EliminationRoutingConfig, @@ -2484,13 +2484,13 @@ where "performing contract_based_routing for profile {}", profile_id.get_string_repr() ); - let client = state + let client = &state .grpc_client .dynamic_routing - .contract_based_client .as_ref() .ok_or(errors::RoutingError::ContractRoutingClientInitializationError) - .attach_printable("contract routing gRPC client not found")?; + .attach_printable("dynamic routing gRPC client not found")? + .contract_based_client; let contract_based_routing_configs = routing::helpers::fetch_dynamic_routing_configs::< api_routing::ContractBasedRoutingConfig, diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs index 52a3b4f1a7..806a01235f 100644 --- a/crates/router/src/core/routing.rs +++ b/crates/router/src/core/routing.rs @@ -1848,10 +1848,10 @@ pub async fn success_based_routing_update_configs( state .grpc_client .dynamic_routing - .success_rate_client .as_ref() - .async_map(|sr_client| async { - sr_client + .async_map(|dr_client| async { + dr_client + .success_rate_client .invalidate_success_rate_routing_keys( profile_id.get_string_repr().into(), state.get_grpc_headers(), @@ -1952,10 +1952,10 @@ pub async fn elimination_routing_update_configs( state .grpc_client .dynamic_routing - .elimination_based_client .as_ref() - .async_map(|er_client| async { - er_client + .async_map(|dr_client| async { + dr_client + .elimination_based_client .invalidate_elimination_bucket( profile_id.get_string_repr().into(), state.get_grpc_headers(), @@ -2287,12 +2287,11 @@ pub async fn contract_based_routing_update_configs( state .grpc_client - .clone() .dynamic_routing - .contract_based_client - .clone() - .async_map(|ct_client| async move { - ct_client + .as_ref() + .async_map(|dr_client| async { + dr_client + .contract_based_client .invalidate_contracts( profile_id.get_string_repr().into(), state.get_grpc_headers(), diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs index 8b4c747d13..32a7b56056 100644 --- a/crates/router/src/core/routing/helpers.rs +++ b/crates/router/src/core/routing/helpers.rs @@ -845,14 +845,14 @@ pub async fn push_metrics_with_update_window_for_success_based_routing( ) -> RouterResult<()> { if let Some(success_based_algo_ref) = dynamic_routing_algo_ref.success_based_algorithm { if success_based_algo_ref.enabled_feature != routing_types::DynamicRoutingFeatures::None { - let client = state + let client = &state .grpc_client .dynamic_routing - .success_rate_client .as_ref() .ok_or(errors::ApiErrorResponse::GenericNotFoundError { - message: "success_rate gRPC client not found".to_string(), - })?; + message: "dynamic routing gRPC client not found".to_string(), + })? + .success_rate_client; let payment_connector = &payment_attempt.connector.clone().ok_or( errors::ApiErrorResponse::GenericNotFoundError { @@ -1214,14 +1214,14 @@ pub async fn update_window_for_elimination_routing( ) -> RouterResult<()> { if let Some(elimination_algo_ref) = dynamic_algo_ref.elimination_routing_algorithm { if elimination_algo_ref.enabled_feature != routing_types::DynamicRoutingFeatures::None { - let client = state + let client = &state .grpc_client .dynamic_routing - .elimination_based_client .as_ref() .ok_or(errors::ApiErrorResponse::GenericNotFoundError { - message: "elimination_rate gRPC client not found".to_string(), - })?; + message: "dynamic routing gRPC client not found".to_string(), + })? + .elimination_based_client; let elimination_routing_config = fetch_dynamic_routing_configs::< routing_types::EliminationRoutingConfig, @@ -1394,14 +1394,14 @@ pub async fn push_metrics_with_update_window_for_contract_based_routing( if let Some(contract_routing_algo_ref) = dynamic_routing_algo_ref.contract_based_routing { if contract_routing_algo_ref.enabled_feature != routing_types::DynamicRoutingFeatures::None { - let client = state + let client = &state .grpc_client .dynamic_routing - .contract_based_client - .clone() + .as_ref() .ok_or(errors::ApiErrorResponse::GenericNotFoundError { - message: "contract_routing gRPC client not found".to_string(), - })?; + message: "dynamic routing gRPC client not found".to_string(), + })? + .contract_based_client; let payment_connector = &payment_attempt.connector.clone().ok_or( errors::ApiErrorResponse::GenericNotFoundError {