From 1f86526250f66c300f916f105512dc3ef311fd9c Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Mon, 30 Nov 2020 13:08:18 -0800 Subject: [PATCH] wtclient: add backoff in negotiation when createSession() fails Currently if the tower hangs up during session negotiation there is no backoff applied. We add backoff here to avoid excessive CPU/network utilization during unexpected failures. --- watchtower/wtclient/session_negotiator.go | 31 +++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/watchtower/wtclient/session_negotiator.go b/watchtower/wtclient/session_negotiator.go index 67be526d..c782deee 100644 --- a/watchtower/wtclient/session_negotiator.go +++ b/watchtower/wtclient/session_negotiator.go @@ -231,6 +231,19 @@ func (n *sessionNegotiator) negotiate() { // backoff. var backoff time.Duration + // Create a closure to update the backoff upon failure such that it + // stays within our min and max backoff parameters. + updateBackoff := func() { + if backoff == 0 { + backoff = n.cfg.MinBackoff + } else { + backoff *= 2 + if backoff > n.cfg.MaxBackoff { + backoff = n.cfg.MaxBackoff + } + } + } + retryWithBackoff: // If we are retrying, wait out the delay before continuing. if backoff > 0 { @@ -251,16 +264,8 @@ retryWithBackoff: // Pull the next candidate from our list of addresses. tower, err := n.cfg.Candidates.Next() if err != nil { - if backoff == 0 { - backoff = n.cfg.MinBackoff - } else { - // We've run out of addresses, double and clamp - // backoff. - backoff *= 2 - if backoff > n.cfg.MaxBackoff { - backoff = n.cfg.MaxBackoff - } - } + // We've run out of addresses, update our backoff. + updateBackoff() log.Debugf("Unable to get new tower candidate, "+ "retrying after %v -- reason: %v", backoff, err) @@ -293,10 +298,14 @@ retryWithBackoff: // get a new session, trying all addresses if necessary. err = n.createSession(tower, keyIndex) if err != nil { + // An unexpected error occurred, updpate our backoff. + updateBackoff() + log.Debugf("Session negotiation with tower=%x "+ "failed, trying again -- reason: %v", tower.IdentityKey.SerializeCompressed(), err) - continue + + goto retryWithBackoff } // Success.