refactor(runtime): 优化管理端摘要查询与维护聚合链路

- 为 provider catalog key 和 video task 列表增加 summary/page 查询与排序能力,减少列表场景读取重字段
- 将多处 SQL 结果读取改为流式收集,降低 `fetch_all` 的内存占用
- 把日/小时统计、钱包日用量等维护任务改为数据库侧 `CTE + upsert` 聚合
- 修复视频任务轮询更新时从本地 snapshot 回填稀疏字段,避免 `prompt` 和请求体信息丢失
This commit is contained in:
AAEE86
2026-04-13 15:44:58 +08:00
committed by fawney19
parent 6aa16ec792
commit b2d85d70ca
55 changed files with 1954 additions and 1382 deletions
@@ -49,7 +49,9 @@ pub(crate) use crate::handlers::admin::provider::pool::runtime::{
};
pub(crate) use crate::handlers::admin::provider::shared::support::AdminProviderPoolRuntimeState;
pub(crate) use crate::handlers::admin::shared::attach_admin_audit_response;
pub(crate) use aether_data_contracts::repository::provider_catalog::ProviderCatalogKeyListQuery;
pub(crate) use aether_data_contracts::repository::provider_catalog::{
ProviderCatalogKeyListOrder, ProviderCatalogKeyListQuery,
};
pub(crate) async fn maybe_build_local_admin_pool_response(
state: &AdminAppState<'_>,
@@ -3,7 +3,7 @@ use super::{
parse_admin_pool_page, parse_admin_pool_page_size, parse_admin_pool_search,
parse_admin_pool_status_filter, pool_payloads, pool_selection,
read_admin_provider_pool_cooldown_key_ids, read_admin_provider_pool_runtime_state,
AdminProviderPoolRuntimeState, ProviderCatalogKeyListQuery,
AdminProviderPoolRuntimeState, ProviderCatalogKeyListOrder, ProviderCatalogKeyListQuery,
ADMIN_POOL_PROVIDER_CATALOG_READER_UNAVAILABLE_DETAIL,
};
use crate::handlers::admin::request::{AdminAppState, AdminRequestContext};
@@ -118,6 +118,7 @@ pub(super) async fn build_admin_pool_list_keys_response(
},
offset: page_offset,
limit: page_size,
order: ProviderCatalogKeyListOrder::Name,
})
.await?;
(key_page.items, key_page.total)
@@ -31,7 +31,7 @@ pub(crate) async fn build_admin_provider_summary_payload(
active_global_model_ids_result,
) = tokio::join!(
state.list_provider_catalog_endpoints_by_provider_ids(&provider_ids),
state.list_provider_catalog_keys_by_provider_ids(&provider_ids),
state.list_provider_catalog_key_summaries_by_provider_ids(&provider_ids),
state.read_provider_quota_snapshot(provider_id),
state.list_provider_model_stats(&provider_ids),
state.list_active_global_model_ids_by_provider_ids(&provider_ids),
@@ -204,7 +204,7 @@ pub(crate) async fn build_admin_providers_summary_payload(
Vec::new()
} else {
state
.list_provider_catalog_keys_by_provider_ids(&provider_ids)
.list_provider_catalog_key_summaries_by_provider_ids(&provider_ids)
.await
.ok()
.unwrap_or_default()
@@ -48,11 +48,11 @@ pub(crate) async fn build_admin_providers_payload(
.ok()
.unwrap_or_default()
};
let keys = if provider_ids.is_empty() {
let key_stats = if provider_ids.is_empty() {
Vec::new()
} else {
state
.list_provider_catalog_keys_by_provider_ids(&provider_ids)
.list_provider_catalog_key_stats_by_provider_ids(&provider_ids)
.await
.ok()
.unwrap_or_default()
@@ -68,9 +68,12 @@ pub(crate) async fn build_admin_providers_payload(
},
);
let has_any_key_by_provider =
keys.into_iter()
.fold(BTreeSet::<String>::new(), |mut acc, key| {
acc.insert(key.provider_id);
key_stats
.into_iter()
.fold(BTreeSet::<String>::new(), |mut acc, stats| {
if stats.total_keys > 0 {
acc.insert(stats.provider_id);
}
acc
});
@@ -1,4 +1,7 @@
use crate::handlers::admin::request::AdminAppState;
use aether_data_contracts::repository::provider_catalog::{
ProviderCatalogKeyListOrder, ProviderCatalogKeyListQuery,
};
use std::time::{SystemTime, UNIX_EPOCH};
pub(crate) async fn build_admin_provider_keys_payload(
@@ -15,30 +18,26 @@ pub(crate) async fn build_admin_provider_keys_payload(
.await
.ok()
.and_then(|mut providers| providers.drain(..).next())?;
let mut keys = state
.list_provider_catalog_keys_by_provider_ids(std::slice::from_ref(&provider.id))
let key_page = state
.list_provider_catalog_key_page(&ProviderCatalogKeyListQuery {
provider_id: provider.id.clone(),
search: None,
is_active: None,
offset: skip,
limit,
order: ProviderCatalogKeyListOrder::CreatedAt,
})
.await
.ok()
.unwrap_or_default();
keys.sort_by(|left, right| {
left.internal_priority
.cmp(&right.internal_priority)
.then_with(|| {
left.created_at_unix_ms
.unwrap_or_default()
.cmp(&right.created_at_unix_ms.unwrap_or_default())
})
.then_with(|| left.id.cmp(&right.id))
});
.ok()?;
let now_unix_secs = SystemTime::now()
.duration_since(UNIX_EPOCH)
.ok()
.map(|duration| duration.as_secs())
.unwrap_or(0);
Some(serde_json::Value::Array(
keys.into_iter()
.skip(skip)
.take(limit)
key_page
.items
.into_iter()
.map(|key| {
state.build_admin_provider_key_response(
&key,