diff options
| author | soryu <soryu@soryu.co> | 2026-01-21 16:23:01 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-01-21 16:23:01 +0000 |
| commit | eed71f82130d7d767cb18bf8ef687166d9143449 (patch) | |
| tree | 81bf1ce3dbe00ae2cbd34644f6bf41e182e1c961 | |
| parent | 0fe52039768b8f6bb60d15fb87b6d330de66d15f (diff) | |
| download | soryu-makima/add-task-branching.tar.gz soryu-makima/add-task-branching.zip | |
feat(server): Add background cleanup for stale anonymous tasksmakima/add-task-branching
Integrate the anonymous task cleanup into the server startup:
- Run cleanup on server startup to handle tasks from previous runs
- Spawn a background task that runs cleanup every 24 hours
- Delete anonymous tasks (contract_id = NULL) that are in terminal state
(done, failed, merged) and older than 7 days
This follows the same pattern as the existing daemon cleanup mechanism.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| -rw-r--r-- | makima/src/server/mod.rs | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/makima/src/server/mod.rs b/makima/src/server/mod.rs index dadfacd..d575997 100644 --- a/makima/src/server/mod.rs +++ b/makima/src/server/mod.rs @@ -243,14 +243,23 @@ const DAEMON_CLEANUP_INTERVAL_SECS: u64 = 60; /// Daemon heartbeat timeout in seconds (delete daemons older than this) const DAEMON_HEARTBEAT_TIMEOUT_SECS: i64 = 120; +/// Anonymous task cleanup interval in seconds (24 hours) +const ANONYMOUS_TASK_CLEANUP_INTERVAL_SECS: u64 = 24 * 60 * 60; +/// Maximum age in days for anonymous tasks before cleanup +const ANONYMOUS_TASK_MAX_AGE_DAYS: i32 = 7; + /// Run the HTTP server with graceful shutdown support. /// /// # Arguments /// * `state` - Shared application state containing ML models /// * `addr` - Address to bind to (e.g., "0.0.0.0:8080") pub async fn run_server(state: SharedState, addr: &str) -> anyhow::Result<()> { - // Start background daemon cleanup task if database is available + // Start background cleanup tasks if database is available if let Some(pool) = state.db_pool.clone() { + // Clone pool for each background task that needs it + let daemon_cleanup_pool = pool.clone(); + let anonymous_task_cleanup_pool = pool.clone(); + // Initial cleanup of any stale daemons from previous server run match crate::db::repository::delete_stale_daemons(&pool, 0).await { Ok(deleted) if deleted > 0 => { @@ -265,7 +274,25 @@ pub async fn run_server(state: SharedState, addr: &str) -> anyhow::Result<()> { _ => {} } - // Spawn periodic cleanup task + // Initial cleanup of any stale anonymous tasks + match crate::db::repository::cleanup_stale_anonymous_tasks( + &pool, + ANONYMOUS_TASK_MAX_AGE_DAYS, + ).await { + Ok(deleted) if deleted > 0 => { + tracing::info!( + deleted = deleted, + max_age_days = ANONYMOUS_TASK_MAX_AGE_DAYS, + "Cleaned up stale anonymous tasks on startup" + ); + } + Err(e) => { + tracing::warn!(error = %e, "Failed to clean up stale anonymous tasks on startup"); + } + _ => {} + } + + // Spawn periodic daemon cleanup task tokio::spawn(async move { let mut interval = tokio::time::interval( std::time::Duration::from_secs(DAEMON_CLEANUP_INTERVAL_SECS) @@ -273,7 +300,7 @@ pub async fn run_server(state: SharedState, addr: &str) -> anyhow::Result<()> { loop { interval.tick().await; match crate::db::repository::delete_stale_daemons( - &pool, + &daemon_cleanup_pool, DAEMON_HEARTBEAT_TIMEOUT_SECS, ).await { Ok(deleted) if deleted > 0 => { @@ -290,6 +317,32 @@ pub async fn run_server(state: SharedState, addr: &str) -> anyhow::Result<()> { } } }); + + // Spawn periodic anonymous task cleanup task (runs daily) + tokio::spawn(async move { + let mut interval = tokio::time::interval( + std::time::Duration::from_secs(ANONYMOUS_TASK_CLEANUP_INTERVAL_SECS) + ); + loop { + interval.tick().await; + match crate::db::repository::cleanup_stale_anonymous_tasks( + &anonymous_task_cleanup_pool, + ANONYMOUS_TASK_MAX_AGE_DAYS, + ).await { + Ok(deleted) if deleted > 0 => { + tracing::info!( + deleted = deleted, + max_age_days = ANONYMOUS_TASK_MAX_AGE_DAYS, + "Cleaned up stale anonymous tasks" + ); + } + Err(e) => { + tracing::warn!(error = %e, "Failed to clean up stale anonymous tasks"); + } + _ => {} + } + } + }); } let app = make_router(state); |
