feat(jobs/runners): worktree prune two-phase + workspace prune queries/repo methods

This commit is contained in:
2026-05-06 07:55:56 +08:00
parent 0111135e78
commit c50621eeca
8 changed files with 638 additions and 12 deletions
+133
View File
@@ -63,6 +63,26 @@ func (q *Queries) DeleteWorktree(ctx context.Context, id pgtype.UUID) error {
return err
}
const finishPruneRollback = `-- name: FinishPruneRollback :exec
UPDATE workspace_worktrees
SET status = 'idle'
WHERE id = $1 AND status = 'pruning'
`
func (q *Queries) FinishPruneRollback(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, finishPruneRollback, id)
return err
}
const finishPruneSuccess = `-- name: FinishPruneSuccess :exec
DELETE FROM workspace_worktrees WHERE id = $1
`
func (q *Queries) FinishPruneSuccess(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, finishPruneSuccess, id)
return err
}
const getWorktreeByBranchForUpdate = `-- name: GetWorktreeByBranchForUpdate :one
SELECT id, workspace_id, branch, path, status, active_holder, acquired_at, last_used_at, created_at, prune_warning_at FROM workspace_worktrees
WHERE workspace_id = $1 AND branch = $2
@@ -174,6 +194,94 @@ func (q *Queries) ListWorktreesByWorkspace(ctx context.Context, workspaceID pgty
return items, nil
}
const listWorktreesNeedingPrune = `-- name: ListWorktreesNeedingPrune :many
SELECT id, workspace_id, branch, path, status, active_holder, acquired_at, last_used_at, created_at, prune_warning_at FROM workspace_worktrees
WHERE status = 'idle'
AND last_used_at < $1
ORDER BY last_used_at ASC
`
func (q *Queries) ListWorktreesNeedingPrune(ctx context.Context, lastUsedAt pgtype.Timestamptz) ([]WorkspaceWorktree, error) {
rows, err := q.db.Query(ctx, listWorktreesNeedingPrune, lastUsedAt)
if err != nil {
return nil, err
}
defer rows.Close()
var items []WorkspaceWorktree
for rows.Next() {
var i WorkspaceWorktree
if err := rows.Scan(
&i.ID,
&i.WorkspaceID,
&i.Branch,
&i.Path,
&i.Status,
&i.ActiveHolder,
&i.AcquiredAt,
&i.LastUsedAt,
&i.CreatedAt,
&i.PruneWarningAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listWorktreesNeedingPruneWarning = `-- name: ListWorktreesNeedingPruneWarning :many
SELECT id, workspace_id, branch, path, status, active_holder, acquired_at, last_used_at, created_at, prune_warning_at FROM workspace_worktrees
WHERE status = 'idle'
AND prune_warning_at IS NULL
AND last_used_at < $1
ORDER BY last_used_at ASC
`
func (q *Queries) ListWorktreesNeedingPruneWarning(ctx context.Context, lastUsedAt pgtype.Timestamptz) ([]WorkspaceWorktree, error) {
rows, err := q.db.Query(ctx, listWorktreesNeedingPruneWarning, lastUsedAt)
if err != nil {
return nil, err
}
defer rows.Close()
var items []WorkspaceWorktree
for rows.Next() {
var i WorkspaceWorktree
if err := rows.Scan(
&i.ID,
&i.WorkspaceID,
&i.Branch,
&i.Path,
&i.Status,
&i.ActiveHolder,
&i.AcquiredAt,
&i.LastUsedAt,
&i.CreatedAt,
&i.PruneWarningAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const markPruneWarning = `-- name: MarkPruneWarning :exec
UPDATE workspace_worktrees
SET prune_warning_at = now()
WHERE id = $1 AND prune_warning_at IS NULL
`
func (q *Queries) MarkPruneWarning(ctx context.Context, id pgtype.UUID) error {
_, err := q.db.Exec(ctx, markPruneWarning, id)
return err
}
const setWorktreeActive = `-- name: SetWorktreeActive :one
UPDATE workspace_worktrees
SET status = 'active',
@@ -261,3 +369,28 @@ func (q *Queries) SetWorktreePruning(ctx context.Context, id pgtype.UUID) (Works
)
return i, err
}
const tryStartPrune = `-- name: TryStartPrune :one
UPDATE workspace_worktrees
SET status = 'pruning'
WHERE id = $1 AND status = 'idle'
RETURNING id, workspace_id, branch, path, status, active_holder, acquired_at, last_used_at, created_at, prune_warning_at
`
func (q *Queries) TryStartPrune(ctx context.Context, id pgtype.UUID) (WorkspaceWorktree, error) {
row := q.db.QueryRow(ctx, tryStartPrune, id)
var i WorkspaceWorktree
err := row.Scan(
&i.ID,
&i.WorkspaceID,
&i.Branch,
&i.Path,
&i.Status,
&i.ActiveHolder,
&i.AcquiredAt,
&i.LastUsedAt,
&i.CreatedAt,
&i.PruneWarningAt,
)
return i, err
}