summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-21 16:23:01 +0000
committersoryu <soryu@soryu.co>2026-01-21 16:23:01 +0000
commiteed71f82130d7d767cb18bf8ef687166d9143449 (patch)
tree81bf1ce3dbe00ae2cbd34644f6bf41e182e1c961
parent0fe52039768b8f6bb60d15fb87b6d330de66d15f (diff)
downloadsoryu-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.rs59
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);