返回 DeepSeek-Reasonix
codegraph_limit.go
根目录 / internal / plugin / codegraph_limit.go
1 package plugin
2
3 import (
4 "fmt"
5 "sync/atomic"
6 )
7
8 // maxCodeGraphInstances caps how many CodeGraph indexer subprocesses may run
9 // concurrently across the whole process. Each tab/session boots its own plugin
10 // Host (desktop/tabs.go, boot.go), so opening many tabs on large projects used
11 // to spawn one full-tree indexer per tab — exhausting file descriptors and
12 // freezing the machine (#4361, #2992, #3797). A hard cap bounds the blast
13 // radius: once reached, additional CodeGraph instances refuse to start and the
14 // agent degrades to grep/glob, which is the documented manual workaround
15 // (`[codegraph] enabled = false`) applied automatically instead of a crash.
16 const maxCodeGraphInstances = 4
17
18 var liveCodeGraphInstances atomic.Int32
19
20 // acquireCodeGraphSlot reserves one of the bounded CodeGraph instance slots.
21 // It returns a release func (idempotent) and an error when the cap is reached.
22 // The cap only governs CodeGraph; every other stdio plugin is unaffected.
23 func acquireCodeGraphSlot() (func(), error) {
24 n := liveCodeGraphInstances.Add(1)
25 if n > maxCodeGraphInstances {
26 liveCodeGraphInstances.Add(-1)
27 return nil, fmt.Errorf("codegraph: %d instances already running (cap %d); not starting another to avoid file-descriptor exhaustion — close some tabs/sessions or set codegraph off for this one", n-1, maxCodeGraphInstances)
28 }
29 var released atomic.Bool
30 return func() {
31 if released.CompareAndSwap(false, true) {
32 liveCodeGraphInstances.Add(-1)
33 }
34 }, nil
35 }
36
36 lines GO