diff --git a/crates/zclaw-saas/src/scheduler.rs b/crates/zclaw-saas/src/scheduler.rs index 17184eb..cbb4201 100644 --- a/crates/zclaw-saas/src/scheduler.rs +++ b/crates/zclaw-saas/src/scheduler.rs @@ -82,6 +82,7 @@ pub fn start_scheduler(config: &SchedulerConfig, _db: PgPool, dispatcher: Worker pub fn start_db_cleanup_tasks(db: PgPool) { let db_devices = db.clone(); let db_key_pool = db.clone(); + let db_relay = db.clone(); // 每 24 小时清理不活跃设备 tokio::spawn(async move { @@ -128,6 +129,28 @@ pub fn start_db_cleanup_tasks(db: PgPool) { } } }); + + // 每 5 分钟清理超时的 relay_tasks(status=processing 且 updated_at 超过 10 分钟) + tokio::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(300)); + loop { + interval.tick().await; + match sqlx::query( + "UPDATE relay_tasks SET status = 'failed', error_message = 'timeout: upstream not responding', completed_at = NOW() \ + WHERE status = 'processing' AND updated_at < NOW() - INTERVAL '10 minutes'" + ) + .execute(&db_relay) + .await + { + Ok(result) => { + if result.rows_affected() > 0 { + tracing::warn!("Cleaned up {} timed-out relay tasks (>10m processing)", result.rows_affected()); + } + } + Err(e) => tracing::error!("Relay task timeout cleanup failed: {}", e), + } + } + }); } /// 用户任务调度器