Fix concurrent writes to socket

This commit is contained in:
Knut Ahlers 2020-11-22 08:45:33 +01:00
parent c3344534a8
commit dce43ffd99
Signed by: luzifer
GPG key ID: 0066F03ED215AD7D

20
api.go
View file

@ -93,25 +93,41 @@ func handleUpdateSocket(w http.ResponseWriter, r *http.Request) {
defer conn.Close() defer conn.Close()
// Register listener // Register listener
id := uuid.Must(uuid.NewV4()).String() var (
subscribeSocket(id, conn.WriteJSON) 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) defer unsubscribeSocket(id)
keepAlive := time.NewTicker(5 * time.Second) keepAlive := time.NewTicker(5 * time.Second)
defer keepAlive.Stop() defer keepAlive.Stop()
go func() { go func() {
for range keepAlive.C { for range keepAlive.C {
connLock.Lock()
if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil { if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
log.WithError(err).Error("Unable to send ping message") log.WithError(err).Error("Unable to send ping message")
connLock.Unlock()
conn.Close() conn.Close()
return
} }
connLock.Unlock()
} }
}() }()
connLock.Lock()
if err := conn.WriteJSON(compileSocketMessage(msgTypeStore, store)); err != nil { if err := conn.WriteJSON(compileSocketMessage(msgTypeStore, store)); err != nil {
log.WithError(err).Error("Unable to send initial state") log.WithError(err).Error("Unable to send initial state")
return return
} }
connLock.Unlock()
// Handle socket // Handle socket
for { for {