返回 DeepSeek-Reasonix
claim_live.go
根目录 / internal / agent / claim_live.go
1 package agent
2
3 // liveClaim is one active writer slot: the declared capability bound plus the
4 // paths actually reserved at runtime.
5 type liveClaim struct {
6 id int64
7 writer bool
8 declared WritePathSet
9 realized []string
10 opaque bool
11 }
12
13 func (c liveClaim) reservation() WritePathSet {
14 if c.opaque {
15 return wholeReservation(c.declared.WorkspaceRoot)
16 }
17 if len(c.realized) > 0 {
18 return fileReservation(c.declared.WorkspaceRoot, c.realized)
19 }
20 if c.declared.WholeWorkspace {
21 return c.declared
22 }
23 if c.dirOnlyDeclared() {
24 return WritePathSet{}
25 }
26 return c.declared
27 }
28
29 func (c liveClaim) dirOnlyDeclared() bool {
30 if c.declared.WholeWorkspace || len(c.declared.Paths) == 0 {
31 return false
32 }
33 for i := range c.declared.Paths {
34 if c.declared.kindAt(i) != pathKindDir {
35 return false
36 }
37 }
38 return true
39 }
40
41 func wholeReservation(root string) WritePathSet {
42 return WritePathSet{WholeWorkspace: true, WorkspaceRoot: root}
43 }
44
45 func fileReservation(root string, paths []string) WritePathSet {
46 out := WritePathSet{WorkspaceRoot: root, Paths: append([]string(nil), paths...)}
47 out.Kinds = make([]pathKind, len(paths))
48 return out
49 }
50
51 func mergeRealized(existing []string, add WritePathSet) []string {
52 capacity := max(len(existing), len(add.Paths))
53 seen := make(map[string]bool, capacity)
54 out := make([]string, 0, capacity)
55 for _, p := range existing {
56 key := foldPathKey(p)
57 if seen[key] {
58 continue
59 }
60 seen[key] = true
61 out = append(out, p)
62 }
63 for _, p := range add.Paths {
64 key := foldPathKey(p)
65 if seen[key] {
66 continue
67 }
68 seen[key] = true
69 out = append(out, p)
70 }
71 return out
72 }
73
74 // canStartIncomingLocked keeps a queued whole-workspace writer ahead of later
75 // writers. Directory claims have an empty reservation before their first write,
76 // so canStartLocked alone would otherwise let a steady stream bypass it.
77 func (s *SubagentScheduler) canStartIncomingLocked(req AcquireRequest) (bool, string) {
78 if req.Writer {
79 for _, waiter := range s.waiters {
80 if waiter.req.Writer && waiter.req.WritePaths.WholeWorkspace {
81 return false, "queued whole-workspace writer has priority"
82 }
83 }
84 }
85 return s.canStartLocked(req)
86 }
87
87 lines GO