|
|
@@ -22,7 +22,6 @@ import (
|
|
|
"time"
|
|
|
|
|
|
"github.com/coreos/etcd/lease/leasepb"
|
|
|
- "github.com/coreos/etcd/pkg/idutil"
|
|
|
"github.com/coreos/etcd/storage/backend"
|
|
|
)
|
|
|
|
|
|
@@ -41,6 +40,7 @@ var (
|
|
|
|
|
|
ErrNotPrimary = errors.New("not a primary lessor")
|
|
|
ErrLeaseNotFound = errors.New("lease not found")
|
|
|
+ ErrLeaseExists = errors.New("lease already exists")
|
|
|
)
|
|
|
|
|
|
type LeaseID int64
|
|
|
@@ -62,7 +62,7 @@ type Lessor interface {
|
|
|
SetRangeDeleter(dr RangeDeleter)
|
|
|
|
|
|
// Grant grants a lease that expires at least after TTL seconds.
|
|
|
- Grant(ttl int64) *Lease
|
|
|
+ Grant(id LeaseID, ttl int64) (*Lease, error)
|
|
|
// Revoke revokes a lease with given ID. The item attached to the
|
|
|
// given lease will be removed. If the ID does not exist, an error
|
|
|
// will be returned.
|
|
|
@@ -132,21 +132,13 @@ type lessor struct {
|
|
|
stopC chan struct{}
|
|
|
// doneC is a channel whose closure indicates that the lessor is stopped.
|
|
|
doneC chan struct{}
|
|
|
-
|
|
|
- idgen *idutil.Generator
|
|
|
}
|
|
|
|
|
|
-func NewLessor(lessorID uint8, b backend.Backend) Lessor {
|
|
|
- return newLessor(lessorID, b)
|
|
|
+func NewLessor(b backend.Backend) Lessor {
|
|
|
+ return newLessor(b)
|
|
|
}
|
|
|
|
|
|
-func newLessor(lessorID uint8, b backend.Backend) *lessor {
|
|
|
- // ensure the most significant bit of lessorID is 0.
|
|
|
- // so all the IDs generated by id generator will be greater than 0.
|
|
|
- if int8(lessorID) < 0 {
|
|
|
- lessorID = uint8(-int8(lessorID))
|
|
|
- }
|
|
|
-
|
|
|
+func newLessor(b backend.Backend) *lessor {
|
|
|
l := &lessor{
|
|
|
leaseMap: make(map[LeaseID]*Lease),
|
|
|
b: b,
|
|
|
@@ -154,7 +146,6 @@ func newLessor(lessorID uint8, b backend.Backend) *lessor {
|
|
|
expiredC: make(chan []*Lease, 16),
|
|
|
stopC: make(chan struct{}),
|
|
|
doneC: make(chan struct{}),
|
|
|
- idgen: idutil.NewGenerator(lessorID, time.Now()),
|
|
|
}
|
|
|
l.initAndRecover()
|
|
|
|
|
|
@@ -172,13 +163,19 @@ func (le *lessor) SetRangeDeleter(rd RangeDeleter) {
|
|
|
|
|
|
// TODO: when lessor is under high load, it should give out lease
|
|
|
// with longer TTL to reduce renew load.
|
|
|
-func (le *lessor) Grant(ttl int64) *Lease {
|
|
|
- id := LeaseID(le.idgen.Next())
|
|
|
+func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) {
|
|
|
+ if id == NoLease {
|
|
|
+ return nil, ErrLeaseNotFound
|
|
|
+ }
|
|
|
+
|
|
|
+ l := &Lease{ID: id, TTL: ttl, itemSet: make(map[LeaseItem]struct{})}
|
|
|
|
|
|
le.mu.Lock()
|
|
|
defer le.mu.Unlock()
|
|
|
|
|
|
- l := &Lease{ID: id, TTL: ttl, itemSet: make(map[LeaseItem]struct{})}
|
|
|
+ if _, ok := le.leaseMap[id]; ok {
|
|
|
+ return nil, ErrLeaseExists
|
|
|
+ }
|
|
|
|
|
|
if le.primary {
|
|
|
l.refresh()
|
|
|
@@ -186,14 +183,10 @@ func (le *lessor) Grant(ttl int64) *Lease {
|
|
|
l.forever()
|
|
|
}
|
|
|
|
|
|
- if _, ok := le.leaseMap[id]; ok {
|
|
|
- panic("lease: unexpected duplicate ID!")
|
|
|
- }
|
|
|
-
|
|
|
le.leaseMap[id] = l
|
|
|
l.persistTo(le.b)
|
|
|
|
|
|
- return l
|
|
|
+ return l, nil
|
|
|
}
|
|
|
|
|
|
func (le *lessor) Revoke(id LeaseID) error {
|
|
|
@@ -450,7 +443,7 @@ type FakeLessor struct {
|
|
|
|
|
|
func (fl *FakeLessor) SetRangeDeleter(dr RangeDeleter) {}
|
|
|
|
|
|
-func (fl *FakeLessor) Grant(ttl int64) *Lease { return nil }
|
|
|
+func (fl *FakeLessor) Grant(id LeaseID, ttl int64) (*Lease, error) { return nil, nil }
|
|
|
|
|
|
func (fl *FakeLessor) Revoke(id LeaseID) error { return nil }
|
|
|
|