Skip to content

Commit

Permalink
lease: use monotimer for lease
Browse files Browse the repository at this point in the history
lease uses monotimer to calculate its expiration. In this way, changing system time won't affect in lease expiration.

FIX #6700
  • Loading branch information
fanminshi committed Nov 23, 2016
1 parent d5f19f2 commit 7d30c8a
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 13 deletions.
4 changes: 2 additions & 2 deletions build
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ etcd_build() {
if [ -n "${BINDIR}" ]; then out="${BINDIR}"; fi
toggle_failpoints
# Static compilation is useful when etcd is run in a container
CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "$GO_LDFLAGS" -o ${out}/etcd ${REPO_PATH}/cmd/etcd || return
CGO_ENABLED=0 go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "$GO_LDFLAGS" -o ${out}/etcdctl ${REPO_PATH}/cmd/etcdctl || return
go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "$GO_LDFLAGS" -o ${out}/etcd ${REPO_PATH}/cmd/etcd || return
go build $GO_BUILD_FLAGS -installsuffix cgo -ldflags "$GO_LDFLAGS" -o ${out}/etcdctl ${REPO_PATH}/cmd/etcdctl || return
}

etcd_setup_gopath() {
Expand Down
16 changes: 9 additions & 7 deletions lease/lessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"sync"
"time"

"github.com/ScaleFT/monotime"

"github.com/coreos/etcd/lease/leasepb"
"github.com/coreos/etcd/mvcc/backend"
)
Expand All @@ -33,9 +35,9 @@ const (

var (
leaseBucketName = []byte("lease")
// do not use maxInt64 since it can overflow time which will add
// the offset of unix time (1970yr to seconds).
forever = time.Unix(math.MaxInt64>>1, 0)

monoTimer = monotime.New()
forever = time.Duration(1>>63 - 1)

ErrNotPrimary = errors.New("not a primary lessor")
ErrLeaseNotFound = errors.New("lease not found")
Expand Down Expand Up @@ -504,8 +506,8 @@ type Lease struct {
ttl int64 // time to live in seconds

itemSet map[LeaseItem]struct{}
// expiry time in unixnano
expiry time.Time
// expiry is time when lease should expire
expiry time.Duration
revokec chan struct{}
}

Expand Down Expand Up @@ -534,7 +536,7 @@ func (l *Lease) TTL() int64 {

// refresh refreshes the expiry of the lease.
func (l *Lease) refresh(extend time.Duration) {
l.expiry = time.Now().Add(extend + time.Second*time.Duration(l.ttl))
l.expiry = extend + monoTimer.Elapsed() + time.Duration(l.ttl)*time.Second
}

// forever sets the expiry of lease to be forever.
Expand All @@ -551,7 +553,7 @@ func (l *Lease) Keys() []string {

// Remaining returns the remaining time of the lease.
func (l *Lease) Remaining() time.Duration {
return l.expiry.Sub(time.Now())
return l.expiry - monoTimer.Elapsed()
}

type LeaseItem struct {
Expand Down
12 changes: 8 additions & 4 deletions lease/lessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import (
"github.com/coreos/etcd/mvcc/backend"
)

const minLeaseTTL = int64(5)
const (
minLeaseTTL = int64(5)
minLeaseTTLDuration = time.Duration(minLeaseTTL) * time.Second
)

// TestLessorGrant ensures Lessor can grant wanted lease.
// The granted lease should have a unique ID with a term
Expand All @@ -48,8 +51,9 @@ func TestLessorGrant(t *testing.T) {
if !reflect.DeepEqual(gl, l) {
t.Errorf("lease = %v, want %v", gl, l)
}
if l.expiry.Sub(time.Now()) < time.Duration(minLeaseTTL)*time.Second-time.Second {
t.Errorf("term = %v, want at least %v", l.expiry.Sub(time.Now()), time.Duration(minLeaseTTL)*time.Second-time.Second)
minLeaseTTLDura
if l.Remaining() < minLeaseTTLDuration-time.Second {
t.Errorf("term = %v, want at least %v", l.Remaining(), minLeaseTTLDuration-time.Second)
}

nl, err := le.Grant(1, 1)
Expand Down Expand Up @@ -152,7 +156,7 @@ func TestLessorRenew(t *testing.T) {
}

l = le.Lookup(l.ID)
if l.expiry.Sub(time.Now()) < 9*time.Second {
if l.Remaining() < 9*time.Second {
t.Errorf("failed to renew the lease")
}
}
Expand Down

0 comments on commit 7d30c8a

Please sign in to comment.