srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/ipc/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ipc/server.go')
-rw-r--r--internal/ipc/server.go27
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})