lease: support mvcc txn

This commit is contained in:
Anthony Romano 2017-01-04 22:30:03 -08:00
parent 33acbb694b
commit f0c184b3a2
2 changed files with 23 additions and 44 deletions

View File

@ -43,28 +43,24 @@ var (
ErrLeaseExists = errors.New("lease already exists") ErrLeaseExists = errors.New("lease already exists")
) )
type LeaseID int64 // TxnDelete is a TxnWrite that only permits deletes. Defined here
// to avoid circular dependency with mvcc.
// RangeDeleter defines an interface with Txn and DeleteRange method. type TxnDelete interface {
// We define this interface only for lessor to limit the number DeleteRange(key, end []byte) (n, rev int64)
// of methods of mvcc.KV to what lessor actually needs. End()
//
// Having a minimum interface makes testing easy.
type RangeDeleter interface {
// TxnBegin see comments on mvcc.KV
TxnBegin() int64
// TxnEnd see comments on mvcc.KV
TxnEnd(txnID int64) error
// TxnDeleteRange see comments on mvcc.KV
TxnDeleteRange(txnID int64, key, end []byte) (n, rev int64, err error)
} }
// RangeDeleter is a TxnDelete constructor.
type RangeDeleter func() TxnDelete
type LeaseID int64
// Lessor owns leases. It can grant, revoke, renew and modify leases for lessee. // Lessor owns leases. It can grant, revoke, renew and modify leases for lessee.
type Lessor interface { type Lessor interface {
// SetRangeDeleter sets the RangeDeleter to the Lessor. // SetRangeDeleter lets the lessor create TxnDeletes to the store.
// Lessor deletes the items in the revoked or expired lease from the // Lessor deletes the items in the revoked or expired lease by creating
// the set RangeDeleter. // new TxnDeletes.
SetRangeDeleter(dr RangeDeleter) SetRangeDeleter(rd RangeDeleter)
// Grant grants a lease that expires at least after TTL seconds. // Grant grants a lease that expires at least after TTL seconds.
Grant(id LeaseID, ttl int64) (*Lease, error) Grant(id LeaseID, ttl int64) (*Lease, error)
@ -248,17 +244,14 @@ func (le *lessor) Revoke(id LeaseID) error {
return nil return nil
} }
tid := le.rd.TxnBegin() txn := le.rd()
// sort keys so deletes are in same order among all members, // sort keys so deletes are in same order among all members,
// otherwise the backened hashes will be different // otherwise the backened hashes will be different
keys := l.Keys() keys := l.Keys()
sort.StringSlice(keys).Sort() sort.StringSlice(keys).Sort()
for _, key := range keys { for _, key := range keys {
_, _, err := le.rd.TxnDeleteRange(tid, []byte(key), nil) txn.DeleteRange([]byte(key), nil)
if err != nil {
panic(err)
}
} }
le.mu.Lock() le.mu.Lock()
@ -269,11 +262,7 @@ func (le *lessor) Revoke(id LeaseID) error {
// deleting the keys if etcdserver fails in between. // deleting the keys if etcdserver fails in between.
le.b.BatchTx().UnsafeDelete(leaseBucketName, int64ToBytes(int64(l.ID))) le.b.BatchTx().UnsafeDelete(leaseBucketName, int64ToBytes(int64(l.ID)))
err := le.rd.TxnEnd(tid) txn.End()
if err != nil {
panic(err)
}
return nil return nil
} }

View File

@ -86,10 +86,8 @@ func TestLeaseConcurrentKeys(t *testing.T) {
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
defer be.Close() defer be.Close()
fd := &fakeDeleter{}
le := newLessor(be, minLeaseTTL) le := newLessor(be, minLeaseTTL)
le.SetRangeDeleter(fd) le.SetRangeDeleter(func() TxnDelete { return &fakeDeleter{} })
// grant a lease with long term (100 seconds) to // grant a lease with long term (100 seconds) to
// avoid early termination during the test. // avoid early termination during the test.
@ -138,7 +136,7 @@ func TestLessorRevoke(t *testing.T) {
fd := &fakeDeleter{} fd := &fakeDeleter{}
le := newLessor(be, minLeaseTTL) le := newLessor(be, minLeaseTTL)
le.SetRangeDeleter(fd) le.SetRangeDeleter(func() TxnDelete { return fd })
// grant a lease with long term (100 seconds) to // grant a lease with long term (100 seconds) to
// avoid early termination during the test. // avoid early termination during the test.
@ -215,10 +213,8 @@ func TestLessorDetach(t *testing.T) {
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
defer be.Close() defer be.Close()
fd := &fakeDeleter{}
le := newLessor(be, minLeaseTTL) le := newLessor(be, minLeaseTTL)
le.SetRangeDeleter(fd) le.SetRangeDeleter(func() TxnDelete { return &fakeDeleter{} })
// grant a lease with long term (100 seconds) to // grant a lease with long term (100 seconds) to
// avoid early termination during the test. // avoid early termination during the test.
@ -382,17 +378,11 @@ type fakeDeleter struct {
deleted []string deleted []string
} }
func (fd *fakeDeleter) TxnBegin() int64 { func (fd *fakeDeleter) End() {}
return 0
}
func (fd *fakeDeleter) TxnEnd(txnID int64) error { func (fd *fakeDeleter) DeleteRange(key, end []byte) (int64, int64) {
return nil
}
func (fd *fakeDeleter) TxnDeleteRange(tid int64, key, end []byte) (int64, int64, error) {
fd.deleted = append(fd.deleted, string(key)+"_"+string(end)) fd.deleted = append(fd.deleted, string(key)+"_"+string(end))
return 0, 0, nil return 0, 0
} }
func NewTestBackend(t *testing.T) (string, backend.Backend) { func NewTestBackend(t *testing.T) (string, backend.Backend) {