From bb830e670fc2c6e191d5db0d39a654716b1aa747 Mon Sep 17 00:00:00 2001 From: Wisdom Arerosuoghene Date: Wed, 6 May 2020 19:30:43 +0100 Subject: [PATCH] multi: CancelPending error for no pending conns. This modifies the CancelPending method of the connection manager to return an error when there are no pending connections for the provided address or the connection manager is already shutting down. This change, in turn, ensures that attempts to remove a pending connection that doesn't exist via RPC returns an error as expected. --- connmgr/connmanager.go | 20 ++++++++++++-------- server.go | 3 +-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/connmgr/connmanager.go b/connmgr/connmanager.go index 660ce0ed..7abeb86b 100644 --- a/connmgr/connmanager.go +++ b/connmgr/connmanager.go @@ -183,7 +183,7 @@ type handleFailed struct { // handleCancelPending is used to remove failing connections from retries. type handleCancelPending struct { addr net.Addr - done chan struct{} + done chan error } // ConnManager provides a manager to handle network connections. @@ -369,14 +369,15 @@ out: idToRemove, connReq = id, req break } - } if connReq != nil { delete(pending, idToRemove) connReq.updateState(ConnCanceled) log.Debugf("Canceled pending connection to %v", msg.addr) + msg.done <- nil + } else { + msg.done <- fmt.Errorf("no pending connection to %v", msg.addr) } - close(msg.done) } case <-cm.quit: @@ -534,11 +535,13 @@ func (cm *ConnManager) Remove(id uint64) { // CancelPending removes the connection corresponding to the given address // from the list of pending failed connections. -func (cm *ConnManager) CancelPending(addr net.Addr) { +// Returns an error if the connection manager is stopped or there is no pending +// connection for the given address. +func (cm *ConnManager) CancelPending(addr net.Addr) error { if atomic.LoadInt32(&cm.stop) != 0 { - return + return fmt.Errorf("connection manager stopped") } - done := make(chan struct{}) + done := make(chan error, 1) select { case cm.requests <- handleCancelPending{addr, done}: @@ -548,9 +551,10 @@ func (cm *ConnManager) CancelPending(addr net.Addr) { // Wait for the connection to be removed from the conn manager's // internal state. select { - case <-done: + case err := <-done: + return err case <-cm.quit: - return + return fmt.Errorf("connection manager stopped") } } diff --git a/server.go b/server.go index dae2c81a..0ed04acf 100644 --- a/server.go +++ b/server.go @@ -1955,8 +1955,7 @@ func (s *server) handleQuery(state *peerState, querymsg interface{}) { msg.reply <- err return } - s.connManager.CancelPending(netAddr) - msg.reply <- nil + msg.reply <- s.connManager.CancelPending(netAddr) case getOutboundGroup: count, ok := state.outboundGroups[msg.key] if ok {