MCPcopy Create free account
hub / github.com/dtormoen/tsk-tsk / clean_tasks

Method clean_tasks

src/task_manager.rs:103–178  ·  view source on GitHub ↗

Delete completed (and optionally failed) tasks that are not parents of active children. Removes terminal-state tasks from storage and deletes their working directories. Skips tasks that are referenced as parents by Queued or Running tasks to avoid orphaning child tasks that depend on them. # Arguments `include_failed` - When true, also clean Failed tasks (not just Complete) `min_age` - When Som

(
        &self,
        include_failed: bool,
        min_age: Option<chrono::Duration>,
    )

Source from the content-addressed store, hash-verified

101 /// * `min_age` - When Some, only clean tasks whose `completed_at` is older than this duration.
102 /// Tasks without a `completed_at` timestamp are never cleaned when an age filter is set.
103 pub async fn clean_tasks(
104 &self,
105 include_failed: bool,
106 min_age: Option<chrono::Duration>,
107 ) -> Result<CleanResult, String> {
108 // Get all tasks to find directories to delete
109 let all_tasks = self
110 .task_storage
111 .list_tasks()
112 .await
113 .map_err(|e| format!("Error listing tasks: {e}"))?;
114
115 // Build set of task IDs that are parents of active (Queued/Running) children
116 let active_parent_ids: HashSet<String> = all_tasks
117 .iter()
118 .filter(|t| t.status == TaskStatus::Queued || t.status == TaskStatus::Running)
119 .flat_map(|t| t.parent_ids.iter().cloned())
120 .collect();
121
122 let now = chrono::Utc::now();
123
124 // Filter for cleanable tasks based on status and age
125 let cleanable_tasks: Vec<&Task> = all_tasks
126 .iter()
127 .filter(|t| {
128 let status_match = t.status == TaskStatus::Complete
129 || (include_failed
130 && (t.status == TaskStatus::Failed || t.status == TaskStatus::Cancelled));
131 if !status_match {
132 return false;
133 }
134 if let Some(min_age) = min_age {
135 match t.completed_at {
136 Some(completed_at) => now - completed_at >= min_age,
137 None => false,
138 }
139 } else {
140 true
141 }
142 })
143 .collect();
144
145 let (deletable, skipped): (Vec<&Task>, Vec<&Task>) = cleanable_tasks
146 .into_iter()
147 .partition(|t| !active_parent_ids.contains(&t.id));
148
149 // Delete directories for deletable tasks
150 for task in &deletable {
151 // The task directory is the parent of the copied repo path
152 if let Some(ref copied_repo_path) = task.copied_repo_path
153 && let Some(task_dir) = copied_repo_path.parent()
154 && crate::file_system::exists(task_dir).await.unwrap_or(false)
155 && let Err(e) = crate::file_system::remove_dir(task_dir).await
156 {
157 eprintln!(
158 "Warning: Failed to delete task directory {}: {}",
159 task.id, e
160 );

Callers 6

test_clean_tasksFunction · 0.80
executeMethod · 0.80
startMethod · 0.80

Calls 4

existsFunction · 0.85
remove_dirFunction · 0.85
list_tasksMethod · 0.80
delete_taskMethod · 0.45