mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
refactor(runtime): 优化管理端摘要查询与维护聚合链路
- 为 provider catalog key 和 video task 列表增加 summary/page 查询与排序能力,减少列表场景读取重字段 - 将多处 SQL 结果读取改为流式收集,降低 `fetch_all` 的内存占用 - 把日/小时统计、钱包日用量等维护任务改为数据库侧 `CTE + upsert` 聚合 - 修复视频任务轮询更新时从本地 snapshot 回填稀疏字段,避免 `prompt` 和请求体信息丢失
This commit is contained in:
@@ -315,7 +315,7 @@ pub(crate) async fn recover_all_admin_key_health(
|
||||
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()
|
||||
|
||||
@@ -69,7 +69,7 @@ pub(crate) async fn build_admin_endpoint_health_status_payload(
|
||||
let mut health_scores_by_format = BTreeMap::<String, Vec<f64>>::new();
|
||||
if !provider_ids.is_empty() {
|
||||
let keys = 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();
|
||||
@@ -235,7 +235,7 @@ pub(crate) async fn build_admin_health_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()
|
||||
|
||||
@@ -60,7 +60,9 @@ pub(super) async fn maybe_build_local_admin_video_tasks_response(
|
||||
let page_size = query_param_value(request_context.query_string(), "page_size")
|
||||
.and_then(|value| value.parse::<usize>().ok())
|
||||
.unwrap_or(20);
|
||||
let response = state.read_video_task_page(&filter, page, page_size).await?;
|
||||
let response = state
|
||||
.read_video_task_page_summary(&filter, page, page_size)
|
||||
.await?;
|
||||
let provider_names = build_admin_video_task_provider_names(state, &response.items).await?;
|
||||
return Ok(Some(
|
||||
Json(json!({
|
||||
|
||||
@@ -58,7 +58,7 @@ pub(super) async fn build_admin_monitoring_provider_name_by_id_and_keys(
|
||||
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((provider_name_by_id, keys))
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -55,6 +55,15 @@ impl<'a> AdminAppState<'a> {
|
||||
crate::async_task::read_video_task_page(self.app, filter, page, page_size).await
|
||||
}
|
||||
|
||||
pub(crate) async fn read_video_task_page_summary(
|
||||
&self,
|
||||
filter: &aether_data_contracts::repository::video_tasks::VideoTaskQueryFilter,
|
||||
page: usize,
|
||||
page_size: usize,
|
||||
) -> Result<crate::async_task::VideoTaskPageResponse, GatewayError> {
|
||||
crate::async_task::read_video_task_page_summary(self.app, filter, page, page_size).await
|
||||
}
|
||||
|
||||
pub(crate) async fn read_video_task_stats(
|
||||
&self,
|
||||
filter: &aether_data_contracts::repository::video_tasks::VideoTaskQueryFilter,
|
||||
|
||||
@@ -69,6 +69,18 @@ impl<'a> AdminAppState<'a> {
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn list_provider_catalog_key_summaries_by_provider_ids(
|
||||
&self,
|
||||
provider_ids: &[String],
|
||||
) -> Result<
|
||||
Vec<aether_data_contracts::repository::provider_catalog::StoredProviderCatalogKey>,
|
||||
GatewayError,
|
||||
> {
|
||||
self.app
|
||||
.list_provider_catalog_key_summaries_by_provider_ids(provider_ids)
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn list_provider_catalog_keys_by_ids(
|
||||
&self,
|
||||
key_ids: &[String],
|
||||
|
||||
@@ -148,7 +148,7 @@ pub(crate) async fn build_admin_module_runtime_state(
|
||||
false
|
||||
} 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()
|
||||
|
||||
@@ -350,7 +350,7 @@ pub(crate) async fn build_api_format_health_monitor_payload(
|
||||
let mut key_counts_by_format = BTreeMap::<String, usize>::new();
|
||||
if options.include_key_count && !provider_ids.is_empty() {
|
||||
let keys = 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();
|
||||
|
||||
@@ -41,7 +41,7 @@ pub(crate) async fn build_admin_keys_grouped_by_format_payload(
|
||||
|
||||
let (endpoints_result, keys_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),
|
||||
);
|
||||
|
||||
let endpoint_base_url_by_provider_and_format = endpoints_result
|
||||
|
||||
Reference in New Issue
Block a user