mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-01 17:00:21 +08:00
fix: keep conversion priority below load balance
This commit is contained in:
@@ -439,6 +439,127 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_balance_distribution_can_precede_conversion_priority() {
|
||||
let mut same_format_low_priority = candidate("same", 10, 0, Some(10));
|
||||
same_format_low_priority.format_preference = (0, 0);
|
||||
let mut cross_format_high_priority = candidate("cross", 0, 0, Some(0));
|
||||
cross_format_high_priority.format_preference = (1, 1);
|
||||
|
||||
let probe_same = candidate("same", 0, 0, Some(0));
|
||||
let mut probe_cross = candidate("cross", 0, 0, Some(0));
|
||||
probe_cross.format_preference = (0, 0);
|
||||
let seed = (0..512)
|
||||
.find(|seed| {
|
||||
ranked_ids(
|
||||
&[probe_same.clone(), probe_cross.clone()],
|
||||
SchedulerRankingContext {
|
||||
priority_mode: SchedulerPriorityMode::Provider,
|
||||
ranking_mode: SchedulerRankingMode::LoadBalance,
|
||||
include_health: false,
|
||||
load_balance_seed: *seed,
|
||||
},
|
||||
)
|
||||
.first()
|
||||
.is_some_and(|provider| provider == "provider-same")
|
||||
})
|
||||
.expect("test seed should put same-format provider first by load balance");
|
||||
|
||||
assert_eq!(
|
||||
ranked_ids(
|
||||
&[same_format_low_priority, cross_format_high_priority],
|
||||
SchedulerRankingContext {
|
||||
priority_mode: SchedulerPriorityMode::Provider,
|
||||
ranking_mode: SchedulerRankingMode::LoadBalance,
|
||||
include_health: false,
|
||||
load_balance_seed: seed,
|
||||
},
|
||||
),
|
||||
vec!["provider-same", "provider-cross"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_balance_conversion_priority_applies_within_provider_distribution() {
|
||||
let mut same_format_low_priority = candidate("same", 10, 0, Some(10));
|
||||
same_format_low_priority.provider_id = "provider-shared".to_string();
|
||||
same_format_low_priority.format_preference = (0, 0);
|
||||
let mut cross_format_high_priority = candidate("cross", 0, 0, Some(0));
|
||||
cross_format_high_priority.provider_id = "provider-shared".to_string();
|
||||
cross_format_high_priority.format_preference = (1, 1);
|
||||
|
||||
let mut probe_same = same_format_low_priority.clone();
|
||||
probe_same.provider_priority = 0;
|
||||
let mut probe_cross = cross_format_high_priority.clone();
|
||||
probe_cross.format_preference = (0, 0);
|
||||
let seed = (0..512)
|
||||
.find(|seed| {
|
||||
ranked_keys(
|
||||
&[probe_same.clone(), probe_cross.clone()],
|
||||
SchedulerRankingContext {
|
||||
priority_mode: SchedulerPriorityMode::Provider,
|
||||
ranking_mode: SchedulerRankingMode::LoadBalance,
|
||||
include_health: false,
|
||||
load_balance_seed: *seed,
|
||||
},
|
||||
)
|
||||
.first()
|
||||
.is_some_and(|key| key == "key-same")
|
||||
})
|
||||
.expect("test seed should put same-format key first by load balance tiebreaker");
|
||||
|
||||
assert_eq!(
|
||||
ranked_keys(
|
||||
&[same_format_low_priority, cross_format_high_priority],
|
||||
SchedulerRankingContext {
|
||||
priority_mode: SchedulerPriorityMode::Provider,
|
||||
ranking_mode: SchedulerRankingMode::LoadBalance,
|
||||
include_health: false,
|
||||
load_balance_seed: seed,
|
||||
},
|
||||
),
|
||||
vec!["key-cross", "key-same"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_balance_distribution_can_precede_format_preference() {
|
||||
let same_format = candidate("same", 0, 0, Some(0));
|
||||
let mut cross_format = candidate("cross", 0, 0, Some(0));
|
||||
cross_format.format_preference = (1, 1);
|
||||
|
||||
let mut probe_cross = cross_format.clone();
|
||||
probe_cross.format_preference = (0, 0);
|
||||
let seed = (0..512)
|
||||
.find(|seed| {
|
||||
ranked_ids(
|
||||
&[same_format.clone(), probe_cross.clone()],
|
||||
SchedulerRankingContext {
|
||||
priority_mode: SchedulerPriorityMode::Provider,
|
||||
ranking_mode: SchedulerRankingMode::LoadBalance,
|
||||
include_health: false,
|
||||
load_balance_seed: *seed,
|
||||
},
|
||||
)
|
||||
.first()
|
||||
.is_some_and(|provider| provider == "provider-cross")
|
||||
})
|
||||
.expect("test seed should put cross-format provider first by load balance");
|
||||
|
||||
assert_eq!(
|
||||
ranked_ids(
|
||||
&[same_format, cross_format],
|
||||
SchedulerRankingContext {
|
||||
priority_mode: SchedulerPriorityMode::Provider,
|
||||
ranking_mode: SchedulerRankingMode::LoadBalance,
|
||||
include_health: false,
|
||||
load_balance_seed: seed,
|
||||
},
|
||||
),
|
||||
vec!["provider-cross", "provider-same"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_balance_provider_mode_randomizes_providers_then_uses_internal_key_priority() {
|
||||
let mut provider_a_primary = candidate("a-primary", 0, 0, Some(0));
|
||||
|
||||
@@ -65,13 +65,29 @@ fn compare_load_balance_base(
|
||||
.cmp(&right.capability_priority)
|
||||
.then_with(|| compare_cross_format_demotion(left, right))
|
||||
.then_with(|| compare_demoted_format_preference(left, right))
|
||||
.then_with(|| compare_load_balance_distribution_slot(left, right, context))
|
||||
.then_with(|| compare_conversion_priority_slot(left, right, context.priority_mode))
|
||||
.then_with(|| compare_load_balance_distribution_tiebreakers(left, right, context))
|
||||
.then_with(|| compare_format_preference(left, right))
|
||||
.then_with(|| compare_load_balance_distribution(left, right, context))
|
||||
.then_with(|| compare_candidate_identity_for_ranking(left, right))
|
||||
.then(left.original_index.cmp(&right.original_index))
|
||||
}
|
||||
|
||||
fn compare_load_balance_distribution(
|
||||
fn compare_conversion_priority_slot(
|
||||
left: &SchedulerRankableCandidate,
|
||||
right: &SchedulerRankableCandidate,
|
||||
priority_mode: crate::SchedulerPriorityMode,
|
||||
) -> Ordering {
|
||||
if left.demote_cross_format || right.demote_cross_format {
|
||||
return Ordering::Equal;
|
||||
}
|
||||
if left.format_preference.0 == 0 && right.format_preference.0 == 0 {
|
||||
return Ordering::Equal;
|
||||
}
|
||||
compare_candidate_priority_slot(left, right, priority_mode)
|
||||
}
|
||||
|
||||
fn compare_load_balance_distribution_slot(
|
||||
left: &SchedulerRankableCandidate,
|
||||
right: &SchedulerRankableCandidate,
|
||||
context: SchedulerRankingContext,
|
||||
@@ -79,16 +95,6 @@ fn compare_load_balance_distribution(
|
||||
match context.priority_mode {
|
||||
crate::SchedulerPriorityMode::Provider => {
|
||||
compare_seeded_provider_hash(left, right, context.load_balance_seed)
|
||||
.then_with(|| {
|
||||
if left.provider_id == right.provider_id {
|
||||
left.key_internal_priority.cmp(&right.key_internal_priority)
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
})
|
||||
.then_with(|| {
|
||||
compare_seeded_candidate_hash(left, right, context.load_balance_seed, "key")
|
||||
})
|
||||
}
|
||||
crate::SchedulerPriorityMode::GlobalKey => {
|
||||
compare_seeded_candidate_hash(left, right, context.load_balance_seed, "global-key")
|
||||
@@ -96,6 +102,22 @@ fn compare_load_balance_distribution(
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_load_balance_distribution_tiebreakers(
|
||||
left: &SchedulerRankableCandidate,
|
||||
right: &SchedulerRankableCandidate,
|
||||
context: SchedulerRankingContext,
|
||||
) -> Ordering {
|
||||
match context.priority_mode {
|
||||
crate::SchedulerPriorityMode::Provider => if left.provider_id == right.provider_id {
|
||||
left.key_internal_priority.cmp(&right.key_internal_priority)
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
.then_with(|| compare_seeded_candidate_hash(left, right, context.load_balance_seed, "key")),
|
||||
crate::SchedulerPriorityMode::GlobalKey => Ordering::Equal,
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_health(
|
||||
left: &SchedulerRankableCandidate,
|
||||
right: &SchedulerRankableCandidate,
|
||||
|
||||
Reference in New Issue
Block a user