summaryrefslogtreecommitdiff
path: root/internal/lsp/server.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-08-19 21:57:38 +0300
committerPaul Buetow <paul@buetow.org>2025-08-19 21:57:38 +0300
commit9f59e7acd647f9adc0903e9c9655c04495f13a53 (patch)
treeedef52111c7fa87227b3d3d14b3716f458a8e5ed /internal/lsp/server.go
parentef188388102b0377ed506b8767536233575965bb (diff)
lsp: replace time throttle with in-flight guard; improve short-prefix heuristic\n\n- Prevent overlapping LLM requests via llmBusy guard\n- Remove time-based throttle and option plumbing\n- Short-prefix heuristic now skips over trailing whitespace and clamps index\n- Add tests for busy guard and trailing-space allowance
Diffstat (limited to 'internal/lsp/server.go')
-rw-r--r--internal/lsp/server.go30
1 files changed, 21 insertions, 9 deletions
diff --git a/internal/lsp/server.go b/internal/lsp/server.go
index 474020c..7773dd1 100644
--- a/internal/lsp/server.go
+++ b/internal/lsp/server.go
@@ -32,9 +32,8 @@ type Server struct {
triggerChars []string
// If set, used as the LSP coding temperature for all LLM calls
codingTemperature *float64
- // Throttling for LLM-powered completion
- lastLLMCompletion time.Time
- minCompletionInterval time.Duration
+ // Concurrency guard: prevent overlapping LLM requests (esp. completions)
+ llmBusy bool
// LLM request stats
llmReqTotal int64
llmSentBytesTotal int64
@@ -54,7 +53,6 @@ type ServerOptions struct {
Client llm.Client
TriggerCharacters []string
CodingTemperature *float64
- MinCompletionIntervalMs int
}
func NewServer(r io.Reader, w io.Writer, logger *log.Logger, opts ServerOptions) *Server {
@@ -89,14 +87,28 @@ func NewServer(r io.Reader, w io.Writer, logger *log.Logger, opts ServerOptions)
s.triggerChars = append([]string{}, opts.TriggerCharacters...)
}
s.codingTemperature = opts.CodingTemperature
- if opts.MinCompletionIntervalMs <= 0 {
- s.minCompletionInterval = 900 * time.Millisecond
- } else {
- s.minCompletionInterval = time.Duration(opts.MinCompletionIntervalMs) * time.Millisecond
- }
return s
}
+// tryStartLLM attempts to mark the LLM as busy. Returns true when it acquired
+// the guard; false if another LLM request is already running.
+func (s *Server) tryStartLLM() bool {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.llmBusy {
+ return false
+ }
+ s.llmBusy = true
+ return true
+}
+
+// endLLM releases the busy guard for LLM requests.
+func (s *Server) endLLM() {
+ s.mu.Lock()
+ s.llmBusy = false
+ s.mu.Unlock()
+}
+
func (s *Server) Run() error {
for {
body, err := s.readMessage()