mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-09 20:50:20 +08:00
Fix provider key response time overflow
This commit is contained in:
@@ -1238,7 +1238,7 @@ fn build_pool_catalog_key_context(
|
||||
.filter(|count| *count > 0)
|
||||
.zip(key.total_response_time_ms)
|
||||
.map(|(success_count, total_response_time_ms)| {
|
||||
f64::from(total_response_time_ms) / f64::from(success_count)
|
||||
total_response_time_ms as f64 / f64::from(success_count)
|
||||
})
|
||||
.filter(|value| value.is_finite() && *value >= 0.0);
|
||||
|
||||
|
||||
@@ -1202,7 +1202,7 @@ fn provider_query_pool_catalog_key_context(
|
||||
.filter(|count| *count > 0)
|
||||
.zip(key.total_response_time_ms)
|
||||
.map(|(success_count, total_response_time_ms)| {
|
||||
f64::from(total_response_time_ms) / f64::from(success_count)
|
||||
total_response_time_ms as f64 / f64::from(success_count)
|
||||
})
|
||||
.filter(|value| value.is_finite() && *value >= 0.0);
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ pub(crate) async fn build_admin_keys_grouped_by_format_payload(
|
||||
None
|
||||
};
|
||||
let avg_response_time_ms = if success_count > 0 {
|
||||
Some(f64::from(key.total_response_time_ms.unwrap_or(0)) / success_count as f64)
|
||||
Some(key.total_response_time_ms.unwrap_or(0) as f64 / success_count as f64)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
@@ -2309,7 +2309,7 @@ pub(crate) fn build_admin_provider_key_response(
|
||||
let request_count = u64::from(key.request_count.unwrap_or(0));
|
||||
let success_count = u64::from(key.success_count.unwrap_or(0));
|
||||
let error_count = u64::from(key.error_count.unwrap_or(0));
|
||||
let total_response_time_ms = f64::from(key.total_response_time_ms.unwrap_or(0));
|
||||
let total_response_time_ms = key.total_response_time_ms.unwrap_or(0) as f64;
|
||||
let success_rate = if request_count > 0 {
|
||||
success_count as f64 / request_count as f64
|
||||
} else {
|
||||
|
||||
@@ -278,7 +278,7 @@ pub struct StoredProviderCatalogKey {
|
||||
pub total_cost_usd: f64,
|
||||
pub success_count: Option<u32>,
|
||||
pub error_count: Option<u32>,
|
||||
pub total_response_time_ms: Option<u32>,
|
||||
pub total_response_time_ms: Option<u64>,
|
||||
pub last_used_at_unix_secs: Option<u64>,
|
||||
pub auto_fetch_models: bool,
|
||||
pub last_models_fetch_at_unix_secs: Option<u64>,
|
||||
@@ -444,7 +444,7 @@ impl StoredProviderCatalogKey {
|
||||
pub fn with_usage_fields(
|
||||
mut self,
|
||||
error_count: Option<u32>,
|
||||
total_response_time_ms: Option<u32>,
|
||||
total_response_time_ms: Option<u64>,
|
||||
) -> Self {
|
||||
self.error_count = error_count;
|
||||
self.total_response_time_ms = total_response_time_ms;
|
||||
|
||||
@@ -75,7 +75,7 @@ impl InMemoryProviderCatalogReadRepository {
|
||||
));
|
||||
key.total_tokens = apply_i64_delta_to_u64(key.total_tokens, delta.total_tokens);
|
||||
key.total_cost_usd = apply_f64_delta(key.total_cost_usd, delta.total_cost_usd);
|
||||
key.total_response_time_ms = Some(apply_i64_delta_to_u32(
|
||||
key.total_response_time_ms = Some(apply_i64_delta_to_u64(
|
||||
key.total_response_time_ms.unwrap_or_default(),
|
||||
delta.total_response_time_ms,
|
||||
));
|
||||
@@ -123,7 +123,7 @@ impl InMemoryProviderCatalogReadRepository {
|
||||
key.total_tokens = clamp_i64_to_u64(contribution.total_tokens);
|
||||
key.total_cost_usd = contribution.total_cost_usd.max(0.0);
|
||||
key.total_response_time_ms =
|
||||
Some(clamp_i64_to_u32(contribution.total_response_time_ms));
|
||||
Some(clamp_i64_to_u64(contribution.total_response_time_ms));
|
||||
key.last_used_at_unix_secs = contribution.last_used_at_unix_secs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,7 +602,13 @@ WHERE id = ?
|
||||
.bind(key.total_cost_usd)
|
||||
.bind(optional_i64_from_u32(key.success_count).unwrap_or(0))
|
||||
.bind(optional_i64_from_u32(key.error_count).unwrap_or(0))
|
||||
.bind(optional_i64_from_u32(key.total_response_time_ms).unwrap_or(0))
|
||||
.bind(
|
||||
optional_i64_from_u64(
|
||||
key.total_response_time_ms,
|
||||
"provider_api_keys.total_response_time_ms",
|
||||
)?
|
||||
.unwrap_or(0),
|
||||
)
|
||||
.bind(optional_i64_from_u64(
|
||||
key.last_used_at_unix_secs,
|
||||
"provider_api_keys.last_used_at",
|
||||
@@ -1542,7 +1548,7 @@ fn map_key_row(row: &MySqlRow) -> Result<StoredProviderCatalogKey, DataLayerErro
|
||||
row.try_get("error_count").map_sql_err()?,
|
||||
"provider_api_keys.error_count",
|
||||
)?,
|
||||
optional_u32(
|
||||
optional_u64(
|
||||
row.try_get("total_response_time_ms").map_sql_err()?,
|
||||
"provider_api_keys.total_response_time_ms",
|
||||
)?,
|
||||
|
||||
@@ -1301,7 +1301,17 @@ INSERT INTO provider_api_keys (
|
||||
.bind(key.total_cost_usd)
|
||||
.bind(key.success_count.map(i64::from))
|
||||
.bind(key.error_count.map(i64::from))
|
||||
.bind(key.total_response_time_ms.map(i64::from))
|
||||
.bind(
|
||||
key.total_response_time_ms
|
||||
.map(|value| {
|
||||
i64::try_from(value).map_err(|_| {
|
||||
DataLayerError::InvalidInput(format!(
|
||||
"provider catalog key.total_response_time_ms exceeds i64: {value}"
|
||||
))
|
||||
})
|
||||
})
|
||||
.transpose()?,
|
||||
)
|
||||
.bind(key.last_used_at_unix_secs.map(|value| value as f64))
|
||||
.bind(key.last_models_fetch_at_unix_secs.map(|value| value as f64))
|
||||
.bind(&key.last_models_fetch_error)
|
||||
@@ -2378,7 +2388,7 @@ fn map_key_row(row: &PgRow) -> Result<StoredProviderCatalogKey, DataLayerError>
|
||||
.transpose()?;
|
||||
let total_response_time_ms = row_get::<Option<i64>>(row, "total_response_time_ms")?
|
||||
.map(|value| {
|
||||
u32::try_from(value).map_err(|_| {
|
||||
u64::try_from(value).map_err(|_| {
|
||||
DataLayerError::UnexpectedValue(format!(
|
||||
"invalid provider_api_keys.total_response_time_ms: {value}"
|
||||
))
|
||||
|
||||
@@ -1026,7 +1026,13 @@ WHERE id = ?
|
||||
.bind(key.total_cost_usd)
|
||||
.bind(optional_i64_from_u32(key.success_count).unwrap_or(0))
|
||||
.bind(optional_i64_from_u32(key.error_count).unwrap_or(0))
|
||||
.bind(optional_i64_from_u32(key.total_response_time_ms).unwrap_or(0))
|
||||
.bind(
|
||||
optional_i64_from_u64(
|
||||
key.total_response_time_ms,
|
||||
"provider_api_keys.total_response_time_ms",
|
||||
)?
|
||||
.unwrap_or(0),
|
||||
)
|
||||
.bind(optional_i64_from_u64(
|
||||
key.last_used_at_unix_secs,
|
||||
"provider_api_keys.last_used_at",
|
||||
@@ -2008,7 +2014,7 @@ fn map_key_row(row: &SqliteRow) -> Result<StoredProviderCatalogKey, DataLayerErr
|
||||
row.try_get("error_count").map_sql_err()?,
|
||||
"provider_api_keys.error_count",
|
||||
)?,
|
||||
optional_u32(
|
||||
optional_u64(
|
||||
row.try_get("total_response_time_ms").map_sql_err()?,
|
||||
"provider_api_keys.total_response_time_ms",
|
||||
)?,
|
||||
@@ -2151,6 +2157,7 @@ mod tests {
|
||||
.expect("keys should list");
|
||||
assert_eq!(keys.len(), 1);
|
||||
assert_eq!(keys[0].total_tokens, 1234);
|
||||
assert_eq!(keys[0].total_response_time_ms, Some(u32::MAX as u64 + 1));
|
||||
assert_eq!(keys[0].concurrent_limit, Some(3));
|
||||
|
||||
let page = repository
|
||||
@@ -2303,7 +2310,7 @@ mod tests {
|
||||
Some(10),
|
||||
Some(9),
|
||||
)
|
||||
.with_usage_fields(Some(1), Some(250))
|
||||
.with_usage_fields(Some(1), Some(u32::MAX as u64 + 42))
|
||||
.with_usage_totals(1234, 1.5)
|
||||
.with_health_fields(
|
||||
Some(json!({"openai:chat":{"score":1}})),
|
||||
@@ -2317,6 +2324,10 @@ mod tests {
|
||||
.expect("key should create");
|
||||
assert_eq!(created_key.concurrent_limit, Some(3));
|
||||
assert_eq!(created_key.total_tokens, 1234);
|
||||
assert_eq!(
|
||||
created_key.total_response_time_ms,
|
||||
Some(u32::MAX as u64 + 42)
|
||||
);
|
||||
assert_eq!(
|
||||
created_key.last_models_fetch_error.as_deref(),
|
||||
Some("stale models fetch error")
|
||||
@@ -2443,7 +2454,7 @@ INSERT INTO provider_api_keys (
|
||||
) VALUES (
|
||||
'key-1', 'provider-1', 'default', 'enc-key', 'api_key',
|
||||
'{"cache_1h":true}', 1, '["openai:chat"]', '{"openai:chat":"api_key"}',
|
||||
5, 120, 3, 10, 1234, 1.5, 9, 1, 250, '{"openai:chat":{"score":1}}',
|
||||
5, 120, 3, 10, 1234, 1.5, 9, 1, 4294967296, '{"openai:chat":{"score":1}}',
|
||||
5, 6
|
||||
)
|
||||
"#,
|
||||
|
||||
Reference in New Issue
Block a user