etcdserver, lease: tie lease min ttl to election timeout

release-3.1
Anthony Romano 2016-08-02 10:29:23 -07:00
parent 4db07dbc93
commit bf71497537
3 changed files with 31 additions and 26 deletions

View File

@ -18,6 +18,7 @@ import (
"encoding/json"
"expvar"
"fmt"
"math"
"math/rand"
"net/http"
"os"
@ -393,7 +394,8 @@ func NewServer(cfg *ServerConfig) (srv *EtcdServer, err error) {
srv.applyV2 = &applierV2store{store: srv.store, cluster: srv.cluster}
srv.be = be
srv.lessor = lease.NewLessor(srv.be)
minTTL := time.Duration((3*cfg.ElectionTicks)/2) * time.Duration(cfg.TickMs) * time.Millisecond
srv.lessor = lease.NewLessor(srv.be, int64(math.Ceil(minTTL.Seconds())))
srv.kv = mvcc.New(srv.be, srv.lessor, &srv.consistIndex)
if beExist {
kvindex := srv.kv.ConsistentIndex()

View File

@ -31,8 +31,6 @@ const (
)
var (
minLeaseTTL = int64(5)
leaseBucketName = []byte("lease")
// do not use maxInt64 since it can overflow time which will add
// the offset of unix time (1970yr to seconds).
@ -138,6 +136,10 @@ type lessor struct {
// The leased items can be recovered by iterating all the keys in kv.
b backend.Backend
// minLeaseTTL is the minimum lease TTL that can be granted for a lease. Any
// requests for shorter TTLs are extended to the minimum TTL.
minLeaseTTL int64
expiredC chan []*Lease
// stopC is a channel whose closure indicates that the lessor should be stopped.
stopC chan struct{}
@ -145,14 +147,15 @@ type lessor struct {
doneC chan struct{}
}
func NewLessor(b backend.Backend) Lessor {
return newLessor(b)
func NewLessor(b backend.Backend, minLeaseTTL int64) Lessor {
return newLessor(b, minLeaseTTL)
}
func newLessor(b backend.Backend) *lessor {
func newLessor(b backend.Backend, minLeaseTTL int64) *lessor {
l := &lessor{
leaseMap: make(map[LeaseID]*Lease),
b: b,
leaseMap: make(map[LeaseID]*Lease),
b: b,
minLeaseTTL: minLeaseTTL,
// expiredC is a small buffered chan to avoid unnecessary blocking.
expiredC: make(chan []*Lease, 16),
stopC: make(chan struct{}),
@ -188,6 +191,10 @@ func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) {
return nil, ErrLeaseExists
}
if l.TTL < le.minLeaseTTL {
l.TTL = le.minLeaseTTL
}
if le.primary {
l.refresh(0)
} else {
@ -406,6 +413,9 @@ func (le *lessor) initAndRecover() {
panic("failed to unmarshal lease proto item")
}
ID := LeaseID(lpb.ID)
if lpb.TTL < le.minLeaseTTL {
lpb.TTL = le.minLeaseTTL
}
le.leaseMap[ID] = &Lease{
ID: ID,
TTL: lpb.TTL,
@ -451,22 +461,13 @@ func (l Lease) removeFrom(b backend.Backend) {
b.BatchTx().Unlock()
}
// refresh refreshes the expiry of the lease. It extends the expiry at least
// minLeaseTTL second.
// refresh refreshes the expiry of the lease.
func (l *Lease) refresh(extend time.Duration) {
if l.TTL < minLeaseTTL {
l.TTL = minLeaseTTL
}
l.expiry = time.Now().Add(extend + time.Second*time.Duration(l.TTL))
}
// forever sets the expiry of lease to be forever.
func (l *Lease) forever() {
if l.TTL < minLeaseTTL {
l.TTL = minLeaseTTL
}
l.expiry = forever
}
func (l *Lease) forever() { l.expiry = forever }
type LeaseItem struct {
Key string

View File

@ -26,6 +26,8 @@ import (
"github.com/coreos/etcd/mvcc/backend"
)
const minLeaseTTL = int64(5)
// TestLessorGrant ensures Lessor can grant wanted lease.
// The granted lease should have a unique ID with a term
// that is greater than minLeaseTTL.
@ -34,7 +36,7 @@ func TestLessorGrant(t *testing.T) {
defer os.RemoveAll(dir)
defer be.Close()
le := newLessor(be)
le := newLessor(be, minLeaseTTL)
le.Promote(0)
l, err := le.Grant(1, 1)
@ -82,7 +84,7 @@ func TestLessorRevoke(t *testing.T) {
fd := &fakeDeleter{}
le := newLessor(be)
le := newLessor(be, minLeaseTTL)
le.SetRangeDeleter(fd)
// grant a lease with long term (100 seconds) to
@ -129,10 +131,10 @@ func TestLessorRenew(t *testing.T) {
defer be.Close()
defer os.RemoveAll(dir)
le := newLessor(be)
le := newLessor(be, minLeaseTTL)
le.Promote(0)
l, err := le.Grant(1, 5)
l, err := le.Grant(1, minLeaseTTL)
if err != nil {
t.Fatalf("failed to grant lease (%v)", err)
}
@ -160,7 +162,7 @@ func TestLessorDetach(t *testing.T) {
fd := &fakeDeleter{}
le := newLessor(be)
le := newLessor(be, minLeaseTTL)
le.SetRangeDeleter(fd)
// grant a lease with long term (100 seconds) to
@ -199,7 +201,7 @@ func TestLessorRecover(t *testing.T) {
defer os.RemoveAll(dir)
defer be.Close()
le := newLessor(be)
le := newLessor(be, minLeaseTTL)
l1, err1 := le.Grant(1, 10)
l2, err2 := le.Grant(2, 20)
if err1 != nil || err2 != nil {
@ -207,7 +209,7 @@ func TestLessorRecover(t *testing.T) {
}
// Create a new lessor with the same backend
nle := newLessor(be)
nle := newLessor(be, minLeaseTTL)
nl1 := nle.get(l1.ID)
if nl1 == nil || nl1.TTL != l1.TTL {
t.Errorf("nl1 = %v, want nl1.TTL= %d", nl1.TTL, l1.TTL)