Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cap maximum grpc wait time when heartbeating to heartbeatTimeout/2 #494

Merged
merged 10 commits into from May 9, 2022
4 changes: 3 additions & 1 deletion replication.go
Expand Up @@ -406,8 +406,10 @@ func (r *Raft) heartbeat(s *followerReplication, stopCh chan struct{}) {
r.observe(FailedHeartbeatObservation{PeerID: peer.ID, LastContact: s.LastContact()})
failures++
select {
case <-time.After(backoff(failureWait, failures, maxFailureScale)):
case <-time.After(cappedExponentialBackoff(failureWait, failures, maxFailureScale,
r.config().HeartbeatTimeout)):
case <-stopCh:
return
}
} else {
if failures > 0 {
Expand Down
14 changes: 14 additions & 0 deletions util.go
Expand Up @@ -144,6 +144,20 @@ func backoff(base time.Duration, round, limit uint64) time.Duration {
return base
}

// cappedExponentialBackoff computes the exponential backoff with an adjustable
// cap on the max timeout.
func cappedExponentialBackoff(base time.Duration, round, limit uint64, cap time.Duration) time.Duration {
power := min(round, limit)
for power > 2 {
if base > cap {
return base
HridoyRoy marked this conversation as resolved.
Show resolved Hide resolved
}
base *= 2
power--
}
return base
HridoyRoy marked this conversation as resolved.
Show resolved Hide resolved
}

// Needed for sorting []uint64, used to determine commitment
type uint64Slice []uint64

Expand Down