fix: P0 panic风险修复 + P1编译warnings清零 + P2代码/文档清理
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

P0 安全性:
- account/handlers.rs: .unwrap() → .expect() 语义化错误信息
- relay/handlers.rs: SSE Response .unwrap() → .expect()

P1 编译质量 (6 warnings → 0):
- kernel.rs: 移除未使用的 Capability import 和 config_clone 变量
- pipeline_commands.rs: 未使用变量 id → _id
- db.rs: 移除多余括号
- relay/service.rs: 移除未使用的 StreamExt import
- telemetry/service.rs: 抑制 param_idx 未读赋值警告
- main.rs: TcpKeepalive::with_retries() Linux-only 条件编译

P2 代码清理:
- 移除 handStore/HandsPanel/HandTaskPanel/gateway-api/SchedulerPanel 调试 console.log
- SchedulerPanel: 修复 updateWorkflow 未解构导致 TS 编译错误
- 文档清理 zclaw-channels 已移除 crate 的引用
This commit is contained in:
iven
2026-03-30 11:33:47 +08:00
parent 813b49a986
commit 834aa12076
17 changed files with 51 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
//! ZCLAW SaaS 服务入口
use axum::extract::State;
use socket2::{Domain, Protocol, Socket, TcpKeepalive, Type};
use tower_http::timeout::TimeoutLayer;
use tracing::info;
use zclaw_saas::{config::SaaSConfig, db::init_db, state::AppState};
@@ -57,11 +58,30 @@ async fn main() -> anyhow::Result<()> {
let app = build_router(state).await;
let listener = tokio::net::TcpListener::bind(format!("{}:{}", config.server.host, config.server.port))
.await?;
// 使用 socket2 创建 TCP listener启用 keepalive 防止 CLOSE_WAIT 累积
let bind_addr: std::net::SocketAddr = format!("{}:{}", config.server.host, config.server.port).parse()?;
let domain = if bind_addr.is_ipv6() { Domain::IPV6 } else { Domain::IPV4 };
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
socket.set_reuse_address(true)?;
socket.set_nonblocking(true)?;
let keepalive = TcpKeepalive::new()
.with_time(std::time::Duration::from_secs(60))
.with_interval(std::time::Duration::from_secs(10));
#[cfg(target_os = "linux")]
let keepalive = keepalive.with_retries(3);
socket.set_tcp_keepalive(&keepalive)?;
info!("TCP keepalive enabled: 60s idle, 10s interval");
socket.bind(&bind_addr.into())?;
socket.listen(128)?;
let std_listener: std::net::TcpListener = socket.into();
let listener = tokio::net::TcpListener::from_std(std_listener)?;
info!("SaaS server listening on {}:{}", config.server.host, config.server.port);
axum::serve(listener, app.into_make_service_with_connect_info::<std::net::SocketAddr>()).await?;
axum::serve(listener, app.into_make_service_with_connect_info::<std::net::SocketAddr>())
.with_graceful_shutdown(shutdown_signal())
.await?;
Ok(())
}
@@ -161,8 +181,16 @@ async fn build_router(state: AppState) -> axum::Router {
axum::Router::new()
.merge(public_routes)
.merge(protected_routes)
.layer(TimeoutLayer::new(std::time::Duration::from_secs(30)))
.layer(TimeoutLayer::new(std::time::Duration::from_secs(15)))
.layer(TraceLayer::new_for_http())
.layer(cors)
.with_state(state)
}
/// 监听 Ctrl+C 信号,触发 graceful shutdown
async fn shutdown_signal() {
tokio::signal::ctrl_c()
.await
.expect("Failed to install Ctrl+C handler");
info!("Received shutdown signal, draining connections...");
}