mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-09 04:30:20 +08:00
fix(pool): allow zero cooldown settings
This commit is contained in:
@@ -458,12 +458,10 @@ pub(crate) fn admin_provider_pool_config_from_config_value(
|
||||
rate_limit_cooldown_seconds: pool_advanced
|
||||
.get("rate_limit_cooldown_seconds")
|
||||
.and_then(json_u64)
|
||||
.filter(|value| *value > 0)
|
||||
.unwrap_or(300),
|
||||
overload_cooldown_seconds: pool_advanced
|
||||
.get("overload_cooldown_seconds")
|
||||
.and_then(json_u64)
|
||||
.filter(|value| *value > 0)
|
||||
.unwrap_or(30),
|
||||
probing_enabled: pool_advanced
|
||||
.get("probing_enabled")
|
||||
@@ -672,6 +670,20 @@ mod tests {
|
||||
assert_eq!(config.sticky_session_ttl_seconds, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_zero_cooldown_seconds_to_disable_error_cooldowns() {
|
||||
let config = admin_provider_pool_config_from_config_value(Some(&json!({
|
||||
"pool_advanced": {
|
||||
"rate_limit_cooldown_seconds": 0,
|
||||
"overload_cooldown_seconds": 0
|
||||
}
|
||||
})))
|
||||
.expect("pool config should parse");
|
||||
|
||||
assert_eq!(config.rate_limit_cooldown_seconds, 0);
|
||||
assert_eq!(config.overload_cooldown_seconds, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_legacy_pool_score_weights_from_pool_advanced() {
|
||||
let config = admin_provider_pool_config_from_config_value(Some(&json!({
|
||||
|
||||
@@ -267,15 +267,20 @@ fn resolve_transient_cooldown_ttl(
|
||||
retry_after_seconds: Option<u64>,
|
||||
pool_config: &AdminProviderPoolConfig,
|
||||
) -> u64 {
|
||||
let configured_cooldown_seconds = if status_code == 429 {
|
||||
pool_config.rate_limit_cooldown_seconds
|
||||
} else {
|
||||
pool_config.overload_cooldown_seconds
|
||||
};
|
||||
if configured_cooldown_seconds == 0 {
|
||||
return 0;
|
||||
}
|
||||
if matches!(status_code, 429 | 503) {
|
||||
if let Some(retry_after_seconds) = retry_after_seconds {
|
||||
return retry_after_seconds;
|
||||
}
|
||||
}
|
||||
if status_code == 429 {
|
||||
return pool_config.rate_limit_cooldown_seconds;
|
||||
}
|
||||
pool_config.overload_cooldown_seconds
|
||||
configured_cooldown_seconds
|
||||
}
|
||||
|
||||
async fn set_pool_cooldown(
|
||||
@@ -586,7 +591,7 @@ mod tests {
|
||||
use super::{
|
||||
admin_provider_pool_key_terminal_error_reason, parse_google_quota_cooldown_seconds_at,
|
||||
record_admin_provider_pool_error, record_admin_provider_pool_stream_timeout,
|
||||
record_admin_provider_pool_success,
|
||||
record_admin_provider_pool_success, resolve_transient_cooldown_ttl,
|
||||
};
|
||||
use crate::handlers::admin::provider::pool::runtime::reads::read_admin_provider_pool_runtime_state;
|
||||
use crate::handlers::admin::provider::shared::support::{
|
||||
@@ -781,6 +786,23 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_cooldown_settings_disable_retry_after_transient_cooldowns() {
|
||||
let mut pool_config = sample_pool_config();
|
||||
pool_config.rate_limit_cooldown_seconds = 0;
|
||||
pool_config.overload_cooldown_seconds = 0;
|
||||
|
||||
assert_eq!(
|
||||
resolve_transient_cooldown_ttl(429, Some(120), &pool_config),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_transient_cooldown_ttl(503, Some(120), &pool_config),
|
||||
0
|
||||
);
|
||||
assert_eq!(resolve_transient_cooldown_ttl(500, None, &pool_config), 0);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn success_feedback_writes_sticky_lru_cost_and_latency() {
|
||||
let Some(redis) = start_managed_redis_or_skip().await else {
|
||||
@@ -948,6 +970,55 @@ mod tests {
|
||||
.is_some_and(|ttl| *ttl <= 120 && *ttl >= 100));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn error_feedback_does_not_write_cooldown_when_429_or_529_cooldown_is_zero() {
|
||||
let Some(redis) = start_managed_redis_or_skip().await else {
|
||||
return;
|
||||
};
|
||||
let app = build_runner_app(redis.redis_url(), "pool_runtime_zero_cooldown").await;
|
||||
let runtime = app.runtime_state.as_ref();
|
||||
let mut pool_config = sample_pool_config();
|
||||
pool_config.rate_limit_cooldown_seconds = 0;
|
||||
pool_config.overload_cooldown_seconds = 0;
|
||||
let key_ids = vec!["key-429".to_string(), "key-529".to_string()];
|
||||
|
||||
record_admin_provider_pool_error(
|
||||
runtime,
|
||||
"provider-1",
|
||||
"key-429",
|
||||
&pool_config,
|
||||
429,
|
||||
Some(r#"{"error":{"message":"rate limited"}}"#),
|
||||
Some(&BTreeMap::from([(
|
||||
"Retry-After".to_string(),
|
||||
"120".to_string(),
|
||||
)])),
|
||||
)
|
||||
.await;
|
||||
record_admin_provider_pool_error(
|
||||
runtime,
|
||||
"provider-1",
|
||||
"key-529",
|
||||
&pool_config,
|
||||
529,
|
||||
Some(r#"{"error":{"message":"overloaded"}}"#),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
|
||||
let runtime = read_admin_provider_pool_runtime_state(
|
||||
runtime,
|
||||
"provider-1",
|
||||
&key_ids,
|
||||
&pool_config,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(runtime.cooldown_reason_by_key.is_empty());
|
||||
assert!(runtime.cooldown_ttl_by_key.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn error_feedback_removes_active_probe_member_when_key_becomes_unschedulable() {
|
||||
let Some(redis) = start_managed_redis_or_skip().await else {
|
||||
|
||||
Reference in New Issue
Block a user