diff --git a/internal/server/server.go b/internal/server/server.go index be2bbc9..ffcec2f 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -163,8 +163,9 @@ func (s *Server) Shutdown() { log := s.Child("sessions") s.Lock() - if len(s.sessions) > 0 { - log.Info("broadcasting shutdown to %d active sessions", len(s.sessions)) + numSessions := len(s.sessions) + if numSessions > 0 { + log.Info("broadcasting shutdown to %d active sessions", numSessions) for id, sn := range s.sessions { log.Info("sending done signal to session: %d", id) sn.done <- true @@ -174,7 +175,9 @@ func (s *Server) Shutdown() { } s.Unlock() - log.Info("waiting on connected sessions to shut down") + if numSessions > 0 { + log.Info("waiting on %d connected sessions to shut down", numSessions) + } s.waitOnSessions.Wait() log.Info("all sessions have shut down") }() diff --git a/internal/wire/client.go b/internal/wire/client.go index 47c8e1d..361558f 100644 --- a/internal/wire/client.go +++ b/internal/wire/client.go @@ -87,6 +87,7 @@ func (c *Client) readLoop(notifications chan<- Response) { defer close(notifications) for { + c.Info("waiting for a reader frame") _, r, err := c.conn.NextReader() if err != nil { if websocket.IsCloseError(err, websocket.CloseNormalClosure) { @@ -130,7 +131,7 @@ func (c *Client) writeLoop() { select { case p := <-c.outbox: c.lastSeq++ - req := NewRequest(c.lastSeq, p.v) + req := Request{c.lastSeq, p.v} w, err := c.conn.NextWriter(websocket.TextMessage) if err != nil { diff --git a/internal/wire/request.go b/internal/wire/request.go index b7b519c..c548d20 100644 --- a/internal/wire/request.go +++ b/internal/wire/request.go @@ -1,15 +1,41 @@ package wire +import ( + "encoding/json" + "fmt" +) + type Request struct { - Seq int `json:"seq"` - Type string `json:"type"` - Body interface{} `json:"body"` + Seq int + Body Value +} + +func (r Request) MarshalJSON() ([]byte, error) { + return json.Marshal([]interface{}{r.Seq, r.Body.NetTag(), r.Body}) } -func NewRequest(seq int, v Value) Request { - return Request{ - Seq: seq, - Type: v.NetTag(), - Body: v, +func (r *Request) UnmarshalJSON(b []byte) error { + var parts [3]json.RawMessage + if err := json.Unmarshal(b, &parts); err != nil { + return err + } + if err := json.Unmarshal(parts[0], &r.Seq); err != nil { + return err + } + + var tag string + if err := json.Unmarshal(parts[1], &tag); err != nil { + return err + } + + f, ok := registry[tag] + if !ok { + return fmt.Errorf("unknown tag: %q", tag) + } + v := f() + if err := json.Unmarshal(parts[2], v); err != nil { + return err } + r.Body = v + return nil }