Fixes to worktree cleanup (#137)
This commit is contained in:
32
backend/.sqlx/query-212828320e8d871ab9d83705a040b23bcf0393dc7252177fc539a74657f578ef.json
generated
Normal file
32
backend/.sqlx/query-212828320e8d871ab9d83705a040b23bcf0393dc7252177fc539a74657f578ef.json
generated
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT ta.id as \"attempt_id!: Uuid\", ta.worktree_path, p.git_repo_path as \"git_repo_path!\"\n FROM task_attempts ta\n LEFT JOIN execution_processes ep ON ta.id = ep.task_attempt_id AND ep.completed_at IS NOT NULL\n JOIN tasks t ON ta.task_id = t.id\n JOIN projects p ON t.project_id = p.id\n WHERE ta.worktree_deleted = FALSE\n -- Exclude attempts with any running processes (in progress)\n AND ta.id NOT IN (\n SELECT DISTINCT ep2.task_attempt_id\n FROM execution_processes ep2\n WHERE ep2.completed_at IS NULL\n )\n GROUP BY ta.id, ta.worktree_path, p.git_repo_path, ta.updated_at\n HAVING datetime('now', '-24 hours') > datetime(\n MAX(\n CASE\n WHEN ep.completed_at IS NOT NULL THEN ep.completed_at\n ELSE ta.updated_at\n END\n )\n )\n ORDER BY MAX(\n CASE\n WHEN ep.completed_at IS NOT NULL THEN ep.completed_at\n ELSE ta.updated_at\n END\n ) ASC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "attempt_id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "worktree_path",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "git_repo_path!",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "212828320e8d871ab9d83705a040b23bcf0393dc7252177fc539a74657f578ef"
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT ta.id as \"attempt_id!: Uuid\", ta.worktree_path, p.git_repo_path as \"git_repo_path!\"\n FROM task_attempts ta\n JOIN execution_processes ep ON ta.id = ep.task_attempt_id\n JOIN tasks t ON ta.task_id = t.id\n JOIN projects p ON t.project_id = p.id\n WHERE ep.completed_at IS NOT NULL\n AND ta.worktree_deleted = FALSE\n GROUP BY ta.id, ta.worktree_path, p.git_repo_path\n HAVING datetime('now', '-1 minutes') > datetime(MAX(ep.completed_at))\n AND ta.id NOT IN (\n SELECT DISTINCT ep2.task_attempt_id\n FROM execution_processes ep2\n WHERE ep2.completed_at IS NULL\n )\n ORDER BY MAX(ep.completed_at) ASC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "attempt_id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "worktree_path",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "git_repo_path!",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "deb5c6ffadf9e67460c37d82520da032bc472ff6d0bd658925b312b18c090f1a"
|
||||
}
|
||||
@@ -379,7 +379,9 @@ impl TaskAttempt {
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Find task attempts that are expired (4+ minutes since last activity) and eligible for worktree cleanup
|
||||
/// Find task attempts that are expired (24+ hours since last activity) and eligible for worktree cleanup
|
||||
/// Activity includes: execution completion, task attempt updates (including worktree recreation),
|
||||
/// and any attempts that are currently in progress
|
||||
pub async fn find_expired_for_cleanup(
|
||||
pool: &SqlitePool,
|
||||
) -> Result<Vec<(Uuid, String, String)>, sqlx::Error> {
|
||||
@@ -387,19 +389,31 @@ impl TaskAttempt {
|
||||
r#"
|
||||
SELECT ta.id as "attempt_id!: Uuid", ta.worktree_path, p.git_repo_path as "git_repo_path!"
|
||||
FROM task_attempts ta
|
||||
JOIN execution_processes ep ON ta.id = ep.task_attempt_id
|
||||
LEFT JOIN execution_processes ep ON ta.id = ep.task_attempt_id AND ep.completed_at IS NOT NULL
|
||||
JOIN tasks t ON ta.task_id = t.id
|
||||
JOIN projects p ON t.project_id = p.id
|
||||
WHERE ep.completed_at IS NOT NULL
|
||||
AND ta.worktree_deleted = FALSE
|
||||
GROUP BY ta.id, ta.worktree_path, p.git_repo_path
|
||||
HAVING datetime('now', '-1 minutes') > datetime(MAX(ep.completed_at))
|
||||
WHERE ta.worktree_deleted = FALSE
|
||||
-- Exclude attempts with any running processes (in progress)
|
||||
AND ta.id NOT IN (
|
||||
SELECT DISTINCT ep2.task_attempt_id
|
||||
FROM execution_processes ep2
|
||||
WHERE ep2.completed_at IS NULL
|
||||
)
|
||||
ORDER BY MAX(ep.completed_at) ASC
|
||||
GROUP BY ta.id, ta.worktree_path, p.git_repo_path, ta.updated_at
|
||||
HAVING datetime('now', '-24 hours') > datetime(
|
||||
MAX(
|
||||
CASE
|
||||
WHEN ep.completed_at IS NOT NULL THEN ep.completed_at
|
||||
ELSE ta.updated_at
|
||||
END
|
||||
)
|
||||
)
|
||||
ORDER BY MAX(
|
||||
CASE
|
||||
WHEN ep.completed_at IS NOT NULL THEN ep.completed_at
|
||||
ELSE ta.updated_at
|
||||
END
|
||||
) ASC
|
||||
"#
|
||||
)
|
||||
.fetch_all(pool)
|
||||
|
||||
Reference in New Issue
Block a user