Problem
WatchEvents in internal/syncthing/client.go has no context.Context parameter, so the long-poll HTTP request (75s timeout) can't be cancelled when the TUI or MCP server shuts down. If the caller is looping, there is also no way to stop it cleanly:
func (c *Client) WatchEvents(since int) ([]SyncEvent, int, error) {
// no ctx — can't cancel
if err := c.getLongPoll(path, &raw); err != nil {
return nil, since, err
}
...
}
Same issue applies to getLongPoll which uses http.NewRequest instead of http.NewRequestWithContext.
Fix
- Change signature to
WatchEvents(ctx context.Context, since int) ([]SyncEvent, int, error)
- Thread
ctx into getLongPoll and use http.NewRequestWithContext
- Callers (event loop goroutine) should pass a context derived from a root cancel that fires on app quit
This prevents zombie goroutines and ensures clean shutdown.
Problem
WatchEventsininternal/syncthing/client.gohas nocontext.Contextparameter, so the long-poll HTTP request (75s timeout) can't be cancelled when the TUI or MCP server shuts down. If the caller is looping, there is also no way to stop it cleanly:Same issue applies to
getLongPollwhich useshttp.NewRequestinstead ofhttp.NewRequestWithContext.Fix
WatchEvents(ctx context.Context, since int) ([]SyncEvent, int, error)ctxintogetLongPolland usehttp.NewRequestWithContextThis prevents zombie goroutines and ensures clean shutdown.