You've already forked agentic-coding-workflow
feat(workspace): WorktreeService with acquire/release state machine
This commit is contained in:
@@ -23,6 +23,9 @@ import (
|
||||
// 状态转移方法,不直接操作 pgx.Tx。
|
||||
type Tx interface {
|
||||
GetWorktreeForUpdate(ctx context.Context, wsID uuid.UUID, branch string) (*Worktree, error)
|
||||
// GetWorktreeByIDForUpdate 在事务内对 id 行加 FOR UPDATE — Acquire/Release 必须用它,
|
||||
// GetWorktreeByID 不带行锁,并发时会 TOCTOU。
|
||||
GetWorktreeByIDForUpdate(ctx context.Context, id uuid.UUID) (*Worktree, error)
|
||||
GetWorktreeByID(ctx context.Context, id uuid.UUID) (*Worktree, error)
|
||||
InsertWorktree(ctx context.Context, w *Worktree) (*Worktree, error)
|
||||
SetWorktreeActive(ctx context.Context, id uuid.UUID, holder string) (*Worktree, error)
|
||||
@@ -355,6 +358,17 @@ func (t *pgTx) GetWorktreeByID(ctx context.Context, id uuid.UUID) (*Worktree, er
|
||||
return rowToWorktree(row), nil
|
||||
}
|
||||
|
||||
func (t *pgTx) GetWorktreeByIDForUpdate(ctx context.Context, id uuid.UUID) (*Worktree, error) {
|
||||
row, err := t.q.GetWorktreeByIDForUpdate(ctx, toPgUUID(id))
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, errs.New(errs.CodeNotFound, "worktree not found")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errs.Wrap(err, errs.CodeInternal, "select for update")
|
||||
}
|
||||
return rowToWorktree(row), nil
|
||||
}
|
||||
|
||||
func (t *pgTx) InsertWorktree(ctx context.Context, w *Worktree) (*Worktree, error) {
|
||||
row, err := t.q.CreateWorktree(ctx, workspacesqlc.CreateWorktreeParams{
|
||||
ID: toPgUUID(w.ID),
|
||||
|
||||
Reference in New Issue
Block a user