From c8a26d9888f90da0d6f1df2cb9ac86071e16fe7f Mon Sep 17 00:00:00 2001 From: Yan-Fa Li Date: Tue, 15 Mar 2016 14:54:33 -0700 Subject: [PATCH] Serialize write access to websocket As the gorilla websocket documentation makes clear, it is the callers responsibility to ensure there is only 1 concurrent reader and writer to every websocket. While investigating alternative Broker implementations which are asynchronous, I was able to trigger go data race warnings while writing to the socket from subscriptions which were writing from different goroutines to the same client. Add a simple mutex on the websocketPeer to gate writers on Send. Looking at the current implementation there should only be one reader from the websocket a time which writes to a messages channel. --- websocket.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/websocket.go b/websocket.go index b34d908..cc363af 100644 --- a/websocket.go +++ b/websocket.go @@ -2,6 +2,7 @@ package turnpike import ( "fmt" + "sync" "time" "github.com/gorilla/websocket" @@ -13,6 +14,7 @@ type websocketPeer struct { messages chan Message payloadType int closed bool + writeMutex sync.Mutex } // NewWebsocketPeer connects to the websocket server at the specified url. @@ -56,6 +58,8 @@ func (ep *websocketPeer) Send(msg Message) error { if err != nil { return err } + ep.writeMutex.Lock() + defer ep.writeMutex.Unlock() return ep.conn.WriteMessage(ep.payloadType, b) } func (ep *websocketPeer) Receive() <-chan Message {