Merge pull request #8507 from lorneli/lease_monotime
lease: use monotime in time.Time for Go 1.9release-3.3
commit
eb55917ef6
|
@ -20,22 +20,18 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/etcd/lease/leasepb"
|
"github.com/coreos/etcd/lease/leasepb"
|
||||||
"github.com/coreos/etcd/mvcc/backend"
|
"github.com/coreos/etcd/mvcc/backend"
|
||||||
"github.com/coreos/etcd/pkg/monotime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
// NoLease is a special LeaseID representing the absence of a lease.
|
||||||
// NoLease is a special LeaseID representing the absence of a lease.
|
const NoLease = LeaseID(0)
|
||||||
NoLease = LeaseID(0)
|
|
||||||
|
|
||||||
forever = monotime.Time(math.MaxInt64)
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
forever = time.Time{}
|
||||||
|
|
||||||
leaseBucketName = []byte("lease")
|
leaseBucketName = []byte("lease")
|
||||||
|
|
||||||
// maximum number of leases to revoke per second; configurable for tests
|
// maximum number of leases to revoke per second; configurable for tests
|
||||||
|
@ -564,8 +560,10 @@ func (le *lessor) initAndRecover() {
|
||||||
type Lease struct {
|
type Lease struct {
|
||||||
ID LeaseID
|
ID LeaseID
|
||||||
ttl int64 // time to live in seconds
|
ttl int64 // time to live in seconds
|
||||||
// expiry is time when lease should expire; must be 64-bit aligned.
|
// expiryMu protects concurrent accesses to expiry
|
||||||
expiry monotime.Time
|
expiryMu sync.RWMutex
|
||||||
|
// expiry is time when lease should expire. no expiration when expiry.IsZero() is true
|
||||||
|
expiry time.Time
|
||||||
|
|
||||||
// mu protects concurrent accesses to itemSet
|
// mu protects concurrent accesses to itemSet
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
@ -598,12 +596,18 @@ func (l *Lease) TTL() int64 {
|
||||||
|
|
||||||
// refresh refreshes the expiry of the lease.
|
// refresh refreshes the expiry of the lease.
|
||||||
func (l *Lease) refresh(extend time.Duration) {
|
func (l *Lease) refresh(extend time.Duration) {
|
||||||
t := monotime.Now().Add(extend + time.Duration(l.ttl)*time.Second)
|
newExpiry := time.Now().Add(extend + time.Duration(l.ttl)*time.Second)
|
||||||
atomic.StoreUint64((*uint64)(&l.expiry), uint64(t))
|
l.expiryMu.Lock()
|
||||||
|
defer l.expiryMu.Unlock()
|
||||||
|
l.expiry = newExpiry
|
||||||
}
|
}
|
||||||
|
|
||||||
// forever sets the expiry of lease to be forever.
|
// forever sets the expiry of lease to be forever.
|
||||||
func (l *Lease) forever() { atomic.StoreUint64((*uint64)(&l.expiry), uint64(forever)) }
|
func (l *Lease) forever() {
|
||||||
|
l.expiryMu.Lock()
|
||||||
|
defer l.expiryMu.Unlock()
|
||||||
|
l.expiry = forever
|
||||||
|
}
|
||||||
|
|
||||||
// Keys returns all the keys attached to the lease.
|
// Keys returns all the keys attached to the lease.
|
||||||
func (l *Lease) Keys() []string {
|
func (l *Lease) Keys() []string {
|
||||||
|
@ -618,8 +622,12 @@ func (l *Lease) Keys() []string {
|
||||||
|
|
||||||
// Remaining returns the remaining time of the lease.
|
// Remaining returns the remaining time of the lease.
|
||||||
func (l *Lease) Remaining() time.Duration {
|
func (l *Lease) Remaining() time.Duration {
|
||||||
t := monotime.Time(atomic.LoadUint64((*uint64)(&l.expiry)))
|
l.expiryMu.RLock()
|
||||||
return time.Duration(t - monotime.Now())
|
defer l.expiryMu.RUnlock()
|
||||||
|
if l.expiry.IsZero() {
|
||||||
|
return time.Duration(math.MaxInt64)
|
||||||
|
}
|
||||||
|
return l.expiry.Sub(time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
type LeaseItem struct {
|
type LeaseItem struct {
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
// Copyright (C) 2016 Arista Networks, Inc.
|
|
||||||
// Use of this source code is governed by the Apache License 2.0
|
|
||||||
// that can be found in the COPYING file.
|
|
||||||
|
|
||||||
// This file is intentionally empty.
|
|
||||||
// It's a workaround for https://github.com/golang/go/issues/15006
|
|
|
@ -1,26 +0,0 @@
|
||||||
// Copyright 2016 The etcd Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package monotime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Time represents a point in monotonic time
|
|
||||||
type Time uint64
|
|
||||||
|
|
||||||
func (t Time) Add(d time.Duration) Time {
|
|
||||||
return Time(uint64(t) + uint64(d.Nanoseconds()))
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
// Copyright (C) 2016 Arista Networks, Inc.
|
|
||||||
// Use of this source code is governed by the Apache License 2.0
|
|
||||||
// that can be found in the COPYING file.
|
|
||||||
|
|
||||||
// Package monotime provides a fast monotonic clock source.
|
|
||||||
package monotime
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "unsafe" // required to use //go:linkname
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
//go:linkname nanotime runtime.nanotime
|
|
||||||
func nanotime() int64
|
|
||||||
|
|
||||||
// Now returns the current time in nanoseconds from a monotonic clock.
|
|
||||||
// The time returned is based on some arbitrary platform-specific point in the
|
|
||||||
// past. The time returned is guaranteed to increase monotonically at a
|
|
||||||
// constant rate, unlike time.Now() from the Go standard library, which may
|
|
||||||
// slow down, speed up, jump forward or backward, due to NTP activity or leap
|
|
||||||
// seconds.
|
|
||||||
func Now() Time {
|
|
||||||
return Time(nanotime())
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
// Copyright (C) 2016 Arista Networks, Inc.
|
|
||||||
// Use of this source code is governed by the Apache License 2.0
|
|
||||||
|
|
||||||
// Package monotime provides a fast monotonic clock source.
|
|
||||||
|
|
||||||
package monotime
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNow(t *testing.T) {
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
t1 := Now()
|
|
||||||
t2 := Now()
|
|
||||||
// I honestly thought that we needed >= here, but in some environments
|
|
||||||
// two consecutive calls can return the same value!
|
|
||||||
if t1 > t2 {
|
|
||||||
t.Fatalf("t1=%d should have been less than or equal to t2=%d", t1, t2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue