@@ -99,19 +99,20 @@ type Service struct {
99
99
100
100
// connWrapper is a wrapper to prevent concurrent-write or concurrent-read on the
101
101
// websocket.
102
- // From Gorilla websocket docs:
103
- // Connections support one concurrent reader and one concurrent writer.
104
- // Applications are responsible for ensuring that no more than one goroutine calls the write methods
105
- // - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel
106
- // concurrently and that no more than one goroutine calls the read methods
107
- // - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler
108
- // concurrently.
109
- // The Close and WriteControl methods can be called concurrently with all other methods.
110
102
//
111
- // The connWrapper uses a single mutex for both reading and writing.
103
+ // From Gorilla websocket docs:
104
+ // Connections support one concurrent reader and one concurrent writer.
105
+ // Applications are responsible for ensuring that no more than one goroutine calls the write methods
106
+ // - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel
107
+ // concurrently and that no more than one goroutine calls the read methods
108
+ // - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler
109
+ // concurrently.
110
+ // The Close and WriteControl methods can be called concurrently with all other methods.
112
111
type connWrapper struct {
113
112
conn * websocket.Conn
114
- mu sync.Mutex
113
+
114
+ rlock sync.Mutex
115
+ wlock sync.Mutex
115
116
}
116
117
117
118
func newConnectionWrapper (conn * websocket.Conn ) * connWrapper {
@@ -120,15 +121,17 @@ func newConnectionWrapper(conn *websocket.Conn) *connWrapper {
120
121
121
122
// WriteJSON wraps corresponding method on the websocket but is safe for concurrent calling
122
123
func (w * connWrapper ) WriteJSON (v interface {}) error {
123
- w .mu .Lock ()
124
- defer w .mu .Unlock ()
124
+ w .wlock .Lock ()
125
+ defer w .wlock .Unlock ()
126
+
125
127
return w .conn .WriteJSON (v )
126
128
}
127
129
128
130
// ReadJSON wraps corresponding method on the websocket but is safe for concurrent calling
129
131
func (w * connWrapper ) ReadJSON (v interface {}) error {
130
- w .mu .Lock ()
131
- defer w .mu .Unlock ()
132
+ w .rlock .Lock ()
133
+ defer w .rlock .Unlock ()
134
+
132
135
return w .conn .ReadJSON (v )
133
136
}
134
137
@@ -275,6 +278,7 @@ func (s *Service) loop() {
275
278
continue
276
279
}
277
280
go s .readLoop (conn )
281
+
278
282
// Send the initial stats so our node looks decent from the get go
279
283
if err = s .report (conn ); err != nil {
280
284
log .Warn ("Initial stats report failed" , "err" , err )
0 commit comments