Skip to content

Commit

Permalink
lease: randomize expiry on initial refresh call
Browse files Browse the repository at this point in the history
Randomize the very first expiry on lease recovery
to prevent recovered leases from expiring all at
the same time.

Address etcd-io#8096.

Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
  • Loading branch information
gyuho committed Jun 14, 2017
1 parent ee0c805 commit d6c5035
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lease/lessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"encoding/binary"
"errors"
"math"
"math/rand"
"sort"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -491,6 +492,7 @@ func (le *lessor) initAndRecover() {
itemSet: make(map[LeaseItem]struct{}),
expiry: forever,
revokec: make(chan struct{}),
fresh: true,
}
}
tx.Unlock()
Expand All @@ -508,6 +510,9 @@ type Lease struct {
mu sync.RWMutex
itemSet map[LeaseItem]struct{}
revokec chan struct{}

// 'true' when lease is just recovered
fresh bool
}

func (l *Lease) expired() bool {
Expand Down Expand Up @@ -536,6 +541,13 @@ func (l *Lease) TTL() int64 {
// refresh refreshes the expiry of the lease.
func (l *Lease) refresh(extend time.Duration) {
t := monotime.Now().Add(extend + time.Duration(l.ttl)*time.Second)
// 'fresh' lease only created from 'initAndRecover'
// randomize expiry with 士10%, to prevent such recovered
// leases of same TTL from expiring all at the same time,
if l.fresh {
t.Add(time.Duration(int64(float64(l.ttl)*0.1*rand.Float64())) * time.Second)
l.fresh = false
}
atomic.StoreUint64((*uint64)(&l.expiry), uint64(t))
}

Expand Down

0 comments on commit d6c5035

Please sign in to comment.