Skip to content

Commit 58f4999

Browse files
committed
lease: randomize expiry on initial refresh call
Randomize the very first expiry on lease recovery to prevent recovered leases from expiring all at the same time. Address #8096. Signed-off-by: Gyu-Ho Lee <gyuhox@gmail.com>
1 parent ee0c805 commit 58f4999

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

lease/lessor.go

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"encoding/binary"
1919
"errors"
2020
"math"
21+
"math/rand"
2122
"sort"
2223
"sync"
2324
"sync/atomic"
@@ -491,6 +492,7 @@ func (le *lessor) initAndRecover() {
491492
itemSet: make(map[LeaseItem]struct{}),
492493
expiry: forever,
493494
revokec: make(chan struct{}),
495+
fresh: true,
494496
}
495497
}
496498
tx.Unlock()
@@ -508,6 +510,9 @@ type Lease struct {
508510
mu sync.RWMutex
509511
itemSet map[LeaseItem]struct{}
510512
revokec chan struct{}
513+
514+
// 'true' when lease is just recovered
515+
fresh bool
511516
}
512517

513518
func (l *Lease) expired() bool {
@@ -536,6 +541,19 @@ func (l *Lease) TTL() int64 {
536541
// refresh refreshes the expiry of the lease.
537542
func (l *Lease) refresh(extend time.Duration) {
538543
t := monotime.Now().Add(extend + time.Duration(l.ttl)*time.Second)
544+
// 'fresh' lease only created from 'initAndRecover'
545+
// randomize expiry with 士10%, to prevent such recovered
546+
// leases of same TTL from expiring all at the same time,
547+
if l.fresh {
548+
var delta int64
549+
if l.ttl > 10 {
550+
delta = int64(float64(l.ttl) * 0.1 * rand.Float64())
551+
} else {
552+
delta = rand.Int63n(10)
553+
}
554+
t = t.Add(time.Duration(delta) * time.Second)
555+
l.fresh = false
556+
}
539557
atomic.StoreUint64((*uint64)(&l.expiry), uint64(t))
540558
}
541559

0 commit comments

Comments
 (0)