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.
This commit is contained in:
Conner Fromknecht 2020-11-30 13:08:18 -08:00
parent 5aa59906b5
commit 1f86526250
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7

@ -231,6 +231,19 @@ func (n *sessionNegotiator) negotiate() {
// backoff. // backoff.
var backoff time.Duration 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: retryWithBackoff:
// If we are retrying, wait out the delay before continuing. // If we are retrying, wait out the delay before continuing.
if backoff > 0 { if backoff > 0 {
@ -251,16 +264,8 @@ retryWithBackoff:
// Pull the next candidate from our list of addresses. // Pull the next candidate from our list of addresses.
tower, err := n.cfg.Candidates.Next() tower, err := n.cfg.Candidates.Next()
if err != nil { if err != nil {
if backoff == 0 { // We've run out of addresses, update our backoff.
backoff = n.cfg.MinBackoff updateBackoff()
} else {
// We've run out of addresses, double and clamp
// backoff.
backoff *= 2
if backoff > n.cfg.MaxBackoff {
backoff = n.cfg.MaxBackoff
}
}
log.Debugf("Unable to get new tower candidate, "+ log.Debugf("Unable to get new tower candidate, "+
"retrying after %v -- reason: %v", backoff, err) "retrying after %v -- reason: %v", backoff, err)
@ -293,10 +298,14 @@ retryWithBackoff:
// get a new session, trying all addresses if necessary. // get a new session, trying all addresses if necessary.
err = n.createSession(tower, keyIndex) err = n.createSession(tower, keyIndex)
if err != nil { if err != nil {
// An unexpected error occurred, updpate our backoff.
updateBackoff()
log.Debugf("Session negotiation with tower=%x "+ log.Debugf("Session negotiation with tower=%x "+
"failed, trying again -- reason: %v", "failed, trying again -- reason: %v",
tower.IdentityKey.SerializeCompressed(), err) tower.IdentityKey.SerializeCompressed(), err)
continue
goto retryWithBackoff
} }
// Success. // Success.