perf: 并行化 admin 聚合路由并完善前端缓存预取

- gateway: usage detail / provider summary / pool overview / users list 改为 tokio join 并行拉取依赖数据
- usage: interval timeline 支持自动刷新并按查询区间动态展示,取消服务端 120 分钟过滤并在 ScatterChart 统一封顶
- frontend: 新增管理端导航预取工具及 SidebarNav/MainLayout 触发,admin 读接口统一走 cachedRequest 的短期缓存
- dashboard: request detail 支持短 TTL 缓存并在 UsageRecordsTable mousedown 时预取
- data: migrate 测试在 wait_for_postgres 失败时清理子进程,避免遗留
This commit is contained in:
fawney19
2026-04-19 15:17:25 +08:00
parent 97cd877ce5
commit 41b51f10a9
30 changed files with 619 additions and 243 deletions

View File

@@ -419,9 +419,9 @@ mod tests {
match Self::start(initdb_bin, postgres_bin).await {
Ok(server) => Ok(Some(server)),
Err(err) if postgres_shared_memory_unavailable(err.to_string().as_str()) => {
Err(err) if postgres_local_startup_unavailable(err.to_string().as_str()) => {
eprintln!(
"skipping postgres integration test because local postgres could not allocate shared memory: {err}"
"skipping postgres integration test because local postgres could not start in this environment: {err}"
);
Ok(None)
}
@@ -463,7 +463,7 @@ mod tests {
let log_path = workdir.join("postgres.log");
let stdout = std::fs::File::create(&log_path)?;
let stderr = stdout.try_clone()?;
let child = Command::new(&postgres_bin)
let mut child = Command::new(&postgres_bin)
.arg("-D")
.arg(&data_dir)
.arg("-h")
@@ -489,7 +489,11 @@ mod tests {
.stderr(Stdio::from(stderr))
.spawn()?;
wait_for_postgres(&database_url).await?;
if let Err(err) = wait_for_postgres(&database_url).await {
let _ = child.kill();
let _ = child.wait();
return Err(err);
}
Ok(Self {
child: Some(child),
@@ -544,6 +548,15 @@ mod tests {
|| message.contains("no space left on device"))
}
fn postgres_local_startup_unavailable(message: &str) -> bool {
let message = message.to_ascii_lowercase();
postgres_shared_memory_unavailable(&message)
|| (message.contains("timed out waiting for local postgres")
&& (message.contains("connection refused")
|| message.contains("os error 61")
|| message.contains("os error 111")))
}
async fn wait_for_postgres(database_url: &str) -> Result<(), Box<dyn std::error::Error>> {
let deadline = Instant::now() + Duration::from_secs(10);
loop {