Retry with backoff on session invalidation failure (#2475)

This commit is contained in:
Kyle Havlovitz 2016-11-05 00:53:22 -04:00 committed by James Phillips
parent 7ffa189077
commit 8c157e0acd
2 changed files with 20 additions and 3 deletions

View File

@ -8,6 +8,14 @@ import (
"github.com/hashicorp/consul/consul/structs"
)
const (
// maxInvalidateAttempts limits how many invalidate attempts are made
maxInvalidateAttempts = 6
// invalidateRetryBase is a baseline retry time
invalidateRetryBase = 10 * time.Second
)
// initializeSessionTimers is used when a leader is newly elected to create
// a new map to track session expiration and to reset all the timers from
// the previously known set of timers.
@ -110,12 +118,19 @@ func (s *Server) invalidateSession(id string) {
ID: id,
},
}
s.logger.Printf("[DEBUG] consul.state: Session %s TTL expired", id)
// Apply the update to destroy the session
if _, err := s.raftApply(structs.SessionRequestType, args); err != nil {
// Retry with exponential backoff to invalidate the session
for attempt := uint(0); attempt < maxInvalidateAttempts; attempt++ {
_, err := s.raftApply(structs.SessionRequestType, args)
if err == nil {
s.logger.Printf("[DEBUG] consul.state: Session %s TTL expired", id)
return
}
s.logger.Printf("[ERR] consul.session: Invalidation failed: %v", err)
time.Sleep((1 << attempt) * invalidateRetryBase)
}
s.logger.Printf("[ERR] consul.session: maximum revoke attempts reached for session: %s", id)
}
// clearSessionTimer is used to clear the session time for

View File

@ -143,6 +143,8 @@ func TestResetSessionTimerLocked(t *testing.T) {
defer os.RemoveAll(dir1)
defer s1.Shutdown()
testutil.WaitForLeader(t, s1.RPC, "dc1")
s1.sessionTimersLock.Lock()
s1.resetSessionTimerLocked("foo", 5*time.Millisecond)
s1.sessionTimersLock.Unlock()