返回 DeepSeek-Reasonix
worktree_runtime_admission.go
根目录 / desktop / worktree_runtime_admission.go
1 package main
2
3 import (
4 "fmt"
5
6 "reasonix/internal/control"
7 )
8
9 func noopRuntimeAdmission() {}
10
11 func (a *App) beginProjectRuntimeAdmission(scope, workspaceRoot string) (func(), error) {
12 if scope != "project" {
13 return noopRuntimeAdmission, nil
14 }
15 return a.beginWorkspaceRuntimeAdmission(workspaceRoot)
16 }
17
18 func (a *App) beginChangedProjectRuntimeAdmission(tab *WorkspaceTab, scope, workspaceRoot string) (func(), error) {
19 if scope != "project" {
20 return noopRuntimeAdmission, nil
21 }
22 a.mu.RLock()
23 sameWorkspace := tab.Scope == "project" && sameProjectRoot(tab.WorkspaceRoot, workspaceRoot)
24 a.mu.RUnlock()
25 if sameWorkspace {
26 return noopRuntimeAdmission, nil
27 }
28 return a.beginWorkspaceRuntimeAdmission(workspaceRoot)
29 }
30
31 func (a *App) publishRestoredTab(tab *WorkspaceTab, releaseAdmission func()) {
32 defer releaseAdmission()
33 a.mu.Lock()
34 a.tabs[tab.ID] = tab
35 a.tabOrder = append(a.tabOrder, tab.ID)
36 a.mu.Unlock()
37 }
38
39 // workspaceRuntimeAdmissionErr rejects submits that race cleanup reservation
40 // or controller readiness. Callers must not hold App.mu.
41 func (a *App) workspaceRuntimeAdmissionErr(tab *WorkspaceTab, ctrl control.SessionAPI) error {
42 a.worktreeReservations.mu.Lock()
43 defer a.worktreeReservations.mu.Unlock()
44 a.mu.RLock()
45 defer a.mu.RUnlock()
46 if tab != nil && tab.Scope == "project" {
47 if key := canonicalRuntimeRoot(tab.WorkspaceRoot); key == "" {
48 return fmt.Errorf("workspace identity is unavailable")
49 } else if err := a.workspaceRuntimeReservationErrLocked(key); err != nil {
50 return err
51 }
52 }
53 if tab != nil && ctrl != nil && tab.Ctrl == ctrl {
54 if a.sessionRuntimeViewLocked(tab).Phase == sessionRuntimeReady {
55 return nil
56 }
57 }
58 return a.workspaceNotReadyErrLocked(tab)
59 }
60
61 // workspaceRuntimeReservationErrLocked applies every destructive worktree
62 // lifecycle reservation to one canonical project root. The caller holds
63 // worktreeReservations.mu so a successful check stays ordered with reservation
64 // publication.
65 func (a *App) workspaceRuntimeReservationErrLocked(workspaceKey string) error {
66 if a.workspaceCleanupReservedLocked(workspaceKey) {
67 return fmt.Errorf("workspace cleanup is in progress")
68 }
69 if a.workspaceMergeReservedLocked(workspaceKey) {
70 return fmt.Errorf("workspace merge-back is in progress")
71 }
72 return nil
73 }
74
74 lines GO