on main help sign in
fix: improve shutdown (#1133)
c8bdb0bCarlos Alexandro Becker
internal/llm/agent/mcp-tools.go+2−2
@@ -259,9 +259,9 @@ func updateMCPState(name string, state MCPState, err error, client *client.Clien
259// CloseMCPClients closes all MCP clients. This should be called during application shutdown.
259// CloseMCPClients closes all MCP clients. This should be called during application shutdown.
260func CloseMCPClients() error {
260func CloseMCPClients() error {
261 var errs []error
261 var errs []error
262− for c := range mcpClients.Seq() {
262+ for name, c := range mcpClients.Seq2() {
263 if err := c.Close(); err != nil {
263 if err := c.Close(); err != nil {
264− errs = append(errs, err)
264+ errs = append(errs, fmt.Errorf("close mcp: %s: %w", name, err))
265 }
265 }
266 }
266 }
267 mcpBroker.Shutdown()
267 mcpBroker.Shutdown()
internal/lsp/client.go+7−44
@@ -319,30 +319,6 @@ func (c *Client) NotifyChange(ctx context.Context, filepath string) error {
319 return c.client.NotifyDidChangeTextDocument(ctx, uri, int(fileInfo.Version), changes)
319 return c.client.NotifyDidChangeTextDocument(ctx, uri, int(fileInfo.Version), changes)
320}
320}
321
321
322−// CloseFile closes a file in the LSP server.
323−//
324−// NOTE: this is only ever called on LSP shutdown.
325−func (c *Client) CloseFile(ctx context.Context, filepath string) error {
326− cfg := config.Get()
327− uri := string(protocol.URIFromPath(filepath))
328−
329− if _, exists := c.openFiles.Get(uri); !exists {
330− return nil // Already closed
331− }
332−
333− if cfg.Options.DebugLSP {
334− slog.Debug("Closing file", "file", filepath)
335− }
336−
337− if err := c.client.NotifyDidCloseTextDocument(ctx, uri); err != nil {
338− return err
339− }
340−
341− c.openFiles.Del(uri)
342−
343− return nil
344−}
345−
346// IsFileOpen checks if a file is currently open.
322// IsFileOpen checks if a file is currently open.
347func (c *Client) IsFileOpen(filepath string) bool {
323func (c *Client) IsFileOpen(filepath string) bool {
348 uri := string(protocol.URIFromPath(filepath))
324 uri := string(protocol.URIFromPath(filepath))
@@ -353,29 +329,16 @@ func (c *Client) IsFileOpen(filepath string) bool {
353// CloseAllFiles closes all currently open files.
329// CloseAllFiles closes all currently open files.
354func (c *Client) CloseAllFiles(ctx context.Context) {
330func (c *Client) CloseAllFiles(ctx context.Context) {
355 cfg := config.Get()
331 cfg := config.Get()
356− filesToClose := make([]string, 0, c.openFiles.Len())
332+ debugLSP := cfg != nil && cfg.Options.DebugLSP
357−
358− // First collect all URIs that need to be closed
359 for uri := range c.openFiles.Seq2() {
333 for uri := range c.openFiles.Seq2() {
360− // Convert URI back to file path using proper URI handling
334+ if debugLSP {
361− filePath, err := protocol.DocumentURI(uri).Path()
335+ slog.Debug("Closing file", "file", uri)
362− if err != nil {
363− slog.Error("Failed to convert URI to path for file closing", "uri", uri, "error", err)
364− continue
365 }
336 }
366− filesToClose = append(filesToClose, filePath)
337+ if err := c.client.NotifyDidCloseTextDocument(ctx, uri); err != nil {
367− }
368−
369− // Then close them all
370− for _, filePath := range filesToClose {
371− err := c.CloseFile(ctx, filePath)
372− if err != nil && cfg != nil && cfg.Options.DebugLSP {
373− slog.Warn("Error closing file", "file", filePath, "error", err)
338+ slog.Warn("Error closing rile", "uri", uri, "error", err)
339+ continue
374 }
340 }
375− }
341+ c.openFiles.Del(uri)
376−
377− if cfg != nil && cfg.Options.DebugLSP {
378− slog.Debug("Closed all files", "files", filesToClose)
379 }
342 }
380}
343}
381
344