mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
feat(routing): elimination routing switch for toggling the feature (#6568)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -6,7 +6,7 @@ use crate::routing::{
|
||||
RoutingLinkWrapper, RoutingPayloadWrapper, RoutingRetrieveLinkQuery,
|
||||
RoutingRetrieveLinkQueryWrapper, RoutingRetrieveQuery, SuccessBasedRoutingConfig,
|
||||
SuccessBasedRoutingPayloadWrapper, SuccessBasedRoutingUpdateConfigQuery,
|
||||
ToggleSuccessBasedRoutingQuery, ToggleSuccessBasedRoutingWrapper,
|
||||
ToggleDynamicRoutingQuery, ToggleDynamicRoutingWrapper,
|
||||
};
|
||||
|
||||
impl ApiEventMetric for RoutingKind {
|
||||
@ -79,7 +79,7 @@ impl ApiEventMetric for RoutingRetrieveLinkQueryWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for ToggleSuccessBasedRoutingQuery {
|
||||
impl ApiEventMetric for ToggleDynamicRoutingQuery {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
@ -97,7 +97,7 @@ impl ApiEventMetric for SuccessBasedRoutingPayloadWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for ToggleSuccessBasedRoutingWrapper {
|
||||
impl ApiEventMetric for ToggleDynamicRoutingWrapper {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
|
||||
@ -522,6 +522,92 @@ pub struct DynamicAlgorithmWithTimestamp<T> {
|
||||
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct DynamicRoutingAlgorithmRef {
|
||||
pub success_based_algorithm: Option<SuccessBasedAlgorithm>,
|
||||
pub elimination_routing_algorithm: Option<EliminationRoutingAlgorithm>,
|
||||
}
|
||||
|
||||
pub trait DynamicRoutingAlgoAccessor {
|
||||
fn get_algorithm_id_with_timestamp(
|
||||
self,
|
||||
) -> DynamicAlgorithmWithTimestamp<common_utils::id_type::RoutingId>;
|
||||
fn get_enabled_features(&mut self) -> &mut DynamicRoutingFeatures;
|
||||
}
|
||||
|
||||
impl DynamicRoutingAlgoAccessor for SuccessBasedAlgorithm {
|
||||
fn get_algorithm_id_with_timestamp(
|
||||
self,
|
||||
) -> DynamicAlgorithmWithTimestamp<common_utils::id_type::RoutingId> {
|
||||
self.algorithm_id_with_timestamp
|
||||
}
|
||||
fn get_enabled_features(&mut self) -> &mut DynamicRoutingFeatures {
|
||||
&mut self.enabled_feature
|
||||
}
|
||||
}
|
||||
|
||||
impl DynamicRoutingAlgoAccessor for EliminationRoutingAlgorithm {
|
||||
fn get_algorithm_id_with_timestamp(
|
||||
self,
|
||||
) -> DynamicAlgorithmWithTimestamp<common_utils::id_type::RoutingId> {
|
||||
self.algorithm_id_with_timestamp
|
||||
}
|
||||
fn get_enabled_features(&mut self) -> &mut DynamicRoutingFeatures {
|
||||
&mut self.enabled_feature
|
||||
}
|
||||
}
|
||||
|
||||
impl EliminationRoutingAlgorithm {
|
||||
pub fn new(
|
||||
algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp<
|
||||
common_utils::id_type::RoutingId,
|
||||
>,
|
||||
) -> Self {
|
||||
Self {
|
||||
algorithm_id_with_timestamp,
|
||||
enabled_feature: DynamicRoutingFeatures::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SuccessBasedAlgorithm {
|
||||
pub fn new(
|
||||
algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp<
|
||||
common_utils::id_type::RoutingId,
|
||||
>,
|
||||
) -> Self {
|
||||
Self {
|
||||
algorithm_id_with_timestamp,
|
||||
enabled_feature: DynamicRoutingFeatures::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DynamicRoutingAlgorithmRef {
|
||||
pub fn update(&mut self, new: Self) {
|
||||
if let Some(elimination_routing_algorithm) = new.elimination_routing_algorithm {
|
||||
self.elimination_routing_algorithm = Some(elimination_routing_algorithm)
|
||||
}
|
||||
if let Some(success_based_algorithm) = new.success_based_algorithm {
|
||||
self.success_based_algorithm = Some(success_based_algorithm)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_specific_ref(
|
||||
&mut self,
|
||||
algo_type: DynamicRoutingType,
|
||||
feature_to_enable: DynamicRoutingFeatures,
|
||||
) {
|
||||
match algo_type {
|
||||
DynamicRoutingType::SuccessRateBasedRouting => {
|
||||
self.success_based_algorithm
|
||||
.as_mut()
|
||||
.map(|algo| algo.enabled_feature = feature_to_enable);
|
||||
}
|
||||
DynamicRoutingType::EliminationRouting => {
|
||||
self.elimination_routing_algorithm
|
||||
.as_mut()
|
||||
.map(|algo| algo.enabled_feature = feature_to_enable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
@ -529,11 +615,25 @@ pub struct SuccessBasedAlgorithm {
|
||||
pub algorithm_id_with_timestamp:
|
||||
DynamicAlgorithmWithTimestamp<common_utils::id_type::RoutingId>,
|
||||
#[serde(default)]
|
||||
pub enabled_feature: SuccessBasedRoutingFeatures,
|
||||
pub enabled_feature: DynamicRoutingFeatures,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct EliminationRoutingAlgorithm {
|
||||
pub algorithm_id_with_timestamp:
|
||||
DynamicAlgorithmWithTimestamp<common_utils::id_type::RoutingId>,
|
||||
#[serde(default)]
|
||||
pub enabled_feature: DynamicRoutingFeatures,
|
||||
}
|
||||
|
||||
impl EliminationRoutingAlgorithm {
|
||||
pub fn update_enabled_features(&mut self, feature_to_enable: DynamicRoutingFeatures) {
|
||||
self.enabled_feature = feature_to_enable
|
||||
}
|
||||
}
|
||||
|
||||
impl SuccessBasedAlgorithm {
|
||||
pub fn update_enabled_features(&mut self, feature_to_enable: SuccessBasedRoutingFeatures) {
|
||||
pub fn update_enabled_features(&mut self, feature_to_enable: DynamicRoutingFeatures) {
|
||||
self.enabled_feature = feature_to_enable
|
||||
}
|
||||
}
|
||||
@ -542,26 +642,40 @@ impl DynamicRoutingAlgorithmRef {
|
||||
pub fn update_algorithm_id(
|
||||
&mut self,
|
||||
new_id: common_utils::id_type::RoutingId,
|
||||
enabled_feature: SuccessBasedRoutingFeatures,
|
||||
enabled_feature: DynamicRoutingFeatures,
|
||||
dynamic_routing_type: DynamicRoutingType,
|
||||
) {
|
||||
self.success_based_algorithm = Some(SuccessBasedAlgorithm {
|
||||
algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp {
|
||||
algorithm_id: Some(new_id),
|
||||
timestamp: common_utils::date_time::now_unix_timestamp(),
|
||||
},
|
||||
enabled_feature,
|
||||
})
|
||||
match dynamic_routing_type {
|
||||
DynamicRoutingType::SuccessRateBasedRouting => {
|
||||
self.success_based_algorithm = Some(SuccessBasedAlgorithm {
|
||||
algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp {
|
||||
algorithm_id: Some(new_id),
|
||||
timestamp: common_utils::date_time::now_unix_timestamp(),
|
||||
},
|
||||
enabled_feature,
|
||||
})
|
||||
}
|
||||
DynamicRoutingType::EliminationRouting => {
|
||||
self.elimination_routing_algorithm = Some(EliminationRoutingAlgorithm {
|
||||
algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp {
|
||||
algorithm_id: Some(new_id),
|
||||
timestamp: common_utils::date_time::now_unix_timestamp(),
|
||||
},
|
||||
enabled_feature,
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||
pub struct ToggleSuccessBasedRoutingQuery {
|
||||
pub enable: SuccessBasedRoutingFeatures,
|
||||
pub struct ToggleDynamicRoutingQuery {
|
||||
pub enable: DynamicRoutingFeatures,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, ToSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SuccessBasedRoutingFeatures {
|
||||
pub enum DynamicRoutingFeatures {
|
||||
Metrics,
|
||||
DynamicConnectorSelection,
|
||||
#[default]
|
||||
@ -577,26 +691,52 @@ pub struct SuccessBasedRoutingUpdateConfigQuery {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
pub struct ToggleSuccessBasedRoutingWrapper {
|
||||
pub struct ToggleDynamicRoutingWrapper {
|
||||
pub profile_id: common_utils::id_type::ProfileId,
|
||||
pub feature_to_enable: SuccessBasedRoutingFeatures,
|
||||
pub feature_to_enable: DynamicRoutingFeatures,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
|
||||
pub struct ToggleSuccessBasedRoutingPath {
|
||||
pub struct ToggleDynamicRoutingPath {
|
||||
#[schema(value_type = String)]
|
||||
pub profile_id: common_utils::id_type::ProfileId,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
|
||||
pub struct EliminationRoutingConfig {
|
||||
pub params: Option<Vec<DynamicRoutingConfigParams>>,
|
||||
// pub labels: Option<Vec<String>>,
|
||||
pub elimination_analyser_config: Option<EliminationAnalyserConfig>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
|
||||
pub struct EliminationAnalyserConfig {
|
||||
pub bucket_size: Option<u32>,
|
||||
pub bucket_ttl_in_mins: Option<f64>,
|
||||
}
|
||||
|
||||
impl Default for EliminationRoutingConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
params: Some(vec![DynamicRoutingConfigParams::PaymentMethod]),
|
||||
elimination_analyser_config: Some(EliminationAnalyserConfig {
|
||||
bucket_size: Some(5),
|
||||
bucket_ttl_in_mins: Some(2.0),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)]
|
||||
pub struct SuccessBasedRoutingConfig {
|
||||
pub params: Option<Vec<SuccessBasedRoutingConfigParams>>,
|
||||
pub params: Option<Vec<DynamicRoutingConfigParams>>,
|
||||
pub config: Option<SuccessBasedRoutingConfigBody>,
|
||||
}
|
||||
|
||||
impl Default for SuccessBasedRoutingConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
params: Some(vec![SuccessBasedRoutingConfigParams::PaymentMethod]),
|
||||
params: Some(vec![DynamicRoutingConfigParams::PaymentMethod]),
|
||||
config: Some(SuccessBasedRoutingConfigBody {
|
||||
min_aggregates_size: Some(2),
|
||||
default_success_rate: Some(100.0),
|
||||
@ -611,7 +751,7 @@ impl Default for SuccessBasedRoutingConfig {
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema, strum::Display)]
|
||||
pub enum SuccessBasedRoutingConfigParams {
|
||||
pub enum DynamicRoutingConfigParams {
|
||||
PaymentMethod,
|
||||
PaymentMethodType,
|
||||
AuthenticationType,
|
||||
@ -642,6 +782,12 @@ pub struct SuccessBasedRoutingPayloadWrapper {
|
||||
pub profile_id: common_utils::id_type::ProfileId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, strum::Display, serde::Serialize, serde::Deserialize)]
|
||||
pub enum DynamicRoutingType {
|
||||
SuccessRateBasedRouting,
|
||||
EliminationRouting,
|
||||
}
|
||||
|
||||
impl SuccessBasedRoutingConfig {
|
||||
pub fn update(&mut self, new: Self) {
|
||||
if let Some(params) = new.params {
|
||||
|
||||
Reference in New Issue
Block a user