From dce43ffd99eefbf6dad33b4f0e5989911b91a391 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sun, 22 Nov 2020 08:45:33 +0100 Subject: [PATCH] Fix concurrent writes to socket --- api.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/api.go b/api.go index b92b5b4..289baa6 100644 --- a/api.go +++ b/api.go @@ -93,25 +93,41 @@ func handleUpdateSocket(w http.ResponseWriter, r *http.Request) { defer conn.Close() // Register listener - id := uuid.Must(uuid.NewV4()).String() - subscribeSocket(id, conn.WriteJSON) + var ( + connLock = new(sync.Mutex) + id = uuid.Must(uuid.NewV4()).String() + ) + subscribeSocket(id, func(msg interface{}) error { + connLock.Lock() + defer connLock.Unlock() + + return conn.WriteJSON(msg) + }) defer unsubscribeSocket(id) keepAlive := time.NewTicker(5 * time.Second) defer keepAlive.Stop() go func() { for range keepAlive.C { + connLock.Lock() + if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil { log.WithError(err).Error("Unable to send ping message") + connLock.Unlock() conn.Close() + return } + + connLock.Unlock() } }() + connLock.Lock() if err := conn.WriteJSON(compileSocketMessage(msgTypeStore, store)); err != nil { log.WithError(err).Error("Unable to send initial state") return } + connLock.Unlock() // Handle socket for {