diff options
Diffstat (limited to 'internal/ipc/server.go')
| -rw-r--r-- | internal/ipc/server.go | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/internal/ipc/server.go b/internal/ipc/server.go index 0e839fb..69044af 100644 --- a/internal/ipc/server.go +++ b/internal/ipc/server.go @@ -3,6 +3,7 @@ package ipc import ( "context" "encoding/json" + "io" "log" "net" "sync" @@ -129,13 +130,31 @@ func (s *Server) handleConn(conn net.Conn) { case "subscribe": sub := s.hub.subscribe() defer s.hub.unsubscribe(sub) - for e := range sub { - e := e - if err := enc.Encode(Response{Type: "new", New: &e}); err != nil { + + // The client never sends anything more on this connection, + // but reading it anyway is how we notice it went away when + // no new entry ever arrives to trigger a failed Encode - + // otherwise a subscriber that quits while the daemon is + // idle leaks its goroutine and channel indefinitely. + disconnected := make(chan struct{}) + go func() { + io.Copy(io.Discard, conn) + close(disconnected) + }() + + for { + select { + case e, ok := <-sub: + if !ok { + return + } + if err := enc.Encode(Response{Type: "new", New: &e}); err != nil { + return + } + case <-disconnected: return } } - return default: enc.Encode(Response{Type: "error", Error: "unknown request type: " + req.Type}) |