Browse Source

Exploit the fact the BaseService's closed Quit channel will keep emitting quit signals to close both readRoutine and writeRoutine

pull/777/head
Silas Davis 7 years ago
parent
commit
4cb02d0bf2
No known key found for this signature in database GPG Key ID: 4CBFD0FF2D395219
1 changed files with 4 additions and 8 deletions
  1. +4
    -8
      rpc/lib/client/ws_client.go

+ 4
- 8
rpc/lib/client/ws_client.go View File

@ -51,7 +51,6 @@ type WSClient struct {
backlog chan types.RPCRequest // stores a single user request received during a conn failure
reconnectAfter chan error // reconnect requests
readRoutineQuit chan struct{} // a way for readRoutine to close writeRoutine
writeRoutineQuit chan struct{} // a way for writeRoutine to close readRoutine (on <-BaseService.Quit)
wg sync.WaitGroup
@ -280,7 +279,6 @@ func (c *WSClient) reconnect() error {
func (c *WSClient) startReadWriteRoutines() {
c.wg.Add(2)
c.readRoutineQuit = make(chan struct{})
c.writeRoutineQuit = make(chan struct{})
go c.readRoutine()
go c.writeRoutine()
}
@ -386,9 +384,6 @@ func (c *WSClient) writeRoutine() {
case <-c.readRoutineQuit:
return
case <-c.Quit:
// We need to fan out the quit message from the single BaseService Quit Channel to the readRoutine
// Use a non-blocking close rather than a send in case readRoutine is in the process of quitting
close(c.writeRoutineQuit)
c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
return
}
@ -438,10 +433,11 @@ func (c *WSClient) readRoutine() {
continue
}
c.Logger.Info("got response", "resp", response.Result)
// Combine a non-blocking read on writeRoutineQuit with a non-blocking write on ResponsesCh to avoid blocking
// c.wg.Wait() in c.Stop()
// Combine a non-blocking read on BaseService.Quit with a non-blocking write on ResponsesCh to avoid blocking
// c.wg.Wait() in c.Stop(). Note we rely on Quit being closed so that it sends unlimited Quit signals to stop
// both readRoutine and writeRoutine
select {
case <-c.writeRoutineQuit:
case <-c.Quit:
case c.ResponsesCh <- response:
}
}


Loading…
Cancel
Save