From f491110c5bc427d3a10375640963521f8f26f6d8 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Thu, 17 Mar 2016 10:18:35 -0700 Subject: [PATCH 1/3] test: check clientv3 has no dependency on etcdserver or storage packages --- test | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test b/test index f54ba08ca..242a75aa2 100755 --- a/test +++ b/test @@ -111,8 +111,22 @@ function fmt_tests { fi } -# fail fast on formatting tests +function dep_tests { + echo "Checking package dependencies..." + # don't pull in etcdserver package + pushd clientv3 >/dev/null + badpkg="(etcdserver|storage)" + deps=`go list -f '{{ .Deps }}' | sed 's/ /\n/g' | egrep "${badpkg}" | egrep -v "${badpkg}/" || echo ""` + popd >/dev/null + if [ ! -z "$deps" ]; then + echo -e "clientv3 has masked dependencies:\n${deps}" + exit 255 + fi +} + +# fail fast on static tests fmt_tests +dep_tests unit_tests if [ -n "$INTEGRATION" ]; then From 44753594ecd199868a7e4b80cf3d4c042f17b640 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Thu, 17 Mar 2016 10:08:16 -0700 Subject: [PATCH 2/3] v3rpc: move errors to v3rpc/rpctypes Fixes #4771 --- clientv3/integration/kv_test.go | 10 ++++---- clientv3/integration/lease_test.go | 6 ++--- clientv3/integration/watch_test.go | 3 ++- clientv3/watch.go | 2 +- etcdctlv3/command/make_mirror_command.go | 4 +-- etcdctlv3/command/snapshot_command.go | 4 +-- etcdserver/api/v3rpc/key.go | 27 ++++++++++---------- etcdserver/api/v3rpc/lease.go | 7 ++--- etcdserver/api/v3rpc/member.go | 13 +++++----- etcdserver/api/v3rpc/{ => rpctypes}/error.go | 7 +++-- integration/v3_grpc_test.go | 23 +++++++++-------- integration/v3_lease_test.go | 10 ++++---- 12 files changed, 60 insertions(+), 56 deletions(-) rename etcdserver/api/v3rpc/{ => rpctypes}/error.go (87%) diff --git a/clientv3/integration/kv_test.go b/clientv3/integration/kv_test.go index a141bd7d0..85a3cef1f 100644 --- a/clientv3/integration/kv_test.go +++ b/clientv3/integration/kv_test.go @@ -22,7 +22,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" - "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/integration" "github.com/coreos/etcd/lease" "github.com/coreos/etcd/pkg/testutil" @@ -344,8 +344,8 @@ func TestKVCompact(t *testing.T) { t.Fatalf("couldn't compact kv space (%v)", err) } err = kv.Compact(ctx, 7) - if err == nil || err != v3rpc.ErrCompacted { - t.Fatalf("error got %v, want %v", err, v3rpc.ErrFutureRev) + if err == nil || err != rpctypes.ErrCompacted { + t.Fatalf("error got %v, want %v", err, rpctypes.ErrFutureRev) } wc := clientv3.NewWatcher(clus.RandClient()) @@ -360,8 +360,8 @@ func TestKVCompact(t *testing.T) { } err = kv.Compact(ctx, 1000) - if err == nil || err != v3rpc.ErrFutureRev { - t.Fatalf("error got %v, want %v", err, v3rpc.ErrFutureRev) + if err == nil || err != rpctypes.ErrFutureRev { + t.Fatalf("error got %v, want %v", err, rpctypes.ErrFutureRev) } } diff --git a/clientv3/integration/lease_test.go b/clientv3/integration/lease_test.go index cc1a770c9..76a3b6452 100644 --- a/clientv3/integration/lease_test.go +++ b/clientv3/integration/lease_test.go @@ -20,7 +20,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" - "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/integration" "github.com/coreos/etcd/lease" "github.com/coreos/etcd/pkg/testutil" @@ -70,8 +70,8 @@ func TestLeaseRevoke(t *testing.T) { } _, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) - if err != v3rpc.ErrLeaseNotFound { - t.Fatalf("err = %v, want %v", err, v3rpc.ErrLeaseNotFound) + if err != rpctypes.ErrLeaseNotFound { + t.Fatalf("err = %v, want %v", err, rpctypes.ErrLeaseNotFound) } } diff --git a/clientv3/integration/watch_test.go b/clientv3/integration/watch_test.go index 0ad2d59b7..5b0415807 100644 --- a/clientv3/integration/watch_test.go +++ b/clientv3/integration/watch_test.go @@ -24,6 +24,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/integration" "github.com/coreos/etcd/pkg/testutil" storagepb "github.com/coreos/etcd/storage/storagepb" @@ -362,7 +363,7 @@ func TestWatchCompactRevision(t *testing.T) { if !ok { t.Fatalf("expected wresp, but got closed channel") } - if wresp.Err() != v3rpc.ErrCompacted { + if wresp.Err() != rpctypes.ErrCompacted { t.Fatalf("wresp.Err() expected ErrCompacteed, but got %v", wresp.Err()) } diff --git a/clientv3/watch.go b/clientv3/watch.go index e347cf24d..4d117b548 100644 --- a/clientv3/watch.go +++ b/clientv3/watch.go @@ -20,7 +20,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc" - "github.com/coreos/etcd/etcdserver/api/v3rpc" + v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" storagepb "github.com/coreos/etcd/storage/storagepb" ) diff --git a/etcdctlv3/command/make_mirror_command.go b/etcdctlv3/command/make_mirror_command.go index b2413f4d0..fa105b55f 100644 --- a/etcdctlv3/command/make_mirror_command.go +++ b/etcdctlv3/command/make_mirror_command.go @@ -24,7 +24,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3/mirror" - "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/storage/storagepb" ) @@ -98,7 +98,7 @@ func makeMirror(ctx context.Context, c *clientv3.Client, dc *clientv3.Client) er for wr := range wc { if wr.CompactRevision != 0 { - return v3rpc.ErrCompacted + return rpctypes.ErrCompacted } var rev int64 diff --git a/etcdctlv3/command/snapshot_command.go b/etcdctlv3/command/snapshot_command.go index 7c82eb785..357a2d8fd 100644 --- a/etcdctlv3/command/snapshot_command.go +++ b/etcdctlv3/command/snapshot_command.go @@ -23,7 +23,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3/mirror" - "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" ) // NewSnapshotCommand returns the cobra command for "snapshot". @@ -100,7 +100,7 @@ func snapshot(w io.Writer, c *clientv3.Client, rev int64) int64 { err := <-errc if err != nil { - if err == v3rpc.ErrCompacted { + if err == rpctypes.ErrCompacted { // will get correct compact revision on retry return rev + 1 } diff --git a/etcdserver/api/v3rpc/key.go b/etcdserver/api/v3rpc/key.go index bff524135..133da8b33 100644 --- a/etcdserver/api/v3rpc/key.go +++ b/etcdserver/api/v3rpc/key.go @@ -23,6 +23,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc" "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc/codes" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/lease" "github.com/coreos/etcd/storage" @@ -152,33 +153,33 @@ func (s *kvServer) fillInHeader(h *pb.ResponseHeader) { func checkRangeRequest(r *pb.RangeRequest) error { if len(r.Key) == 0 { - return ErrEmptyKey + return rpctypes.ErrEmptyKey } return nil } func checkPutRequest(r *pb.PutRequest) error { if len(r.Key) == 0 { - return ErrEmptyKey + return rpctypes.ErrEmptyKey } return nil } func checkDeleteRequest(r *pb.DeleteRangeRequest) error { if len(r.Key) == 0 { - return ErrEmptyKey + return rpctypes.ErrEmptyKey } return nil } func checkTxnRequest(r *pb.TxnRequest) error { if len(r.Compare) > MaxOpsPerTxn || len(r.Success) > MaxOpsPerTxn || len(r.Failure) > MaxOpsPerTxn { - return ErrTooManyOps + return rpctypes.ErrTooManyOps } for _, c := range r.Compare { if len(c.Key) == 0 { - return ErrEmptyKey + return rpctypes.ErrEmptyKey } } @@ -203,7 +204,7 @@ func checkTxnRequest(r *pb.TxnRequest) error { return nil } -// checkRequestDupKeys gives ErrDuplicateKey if the same key is modified twice +// checkRequestDupKeys gives rpctypes.ErrDuplicateKey if the same key is modified twice func checkRequestDupKeys(reqs []*pb.RequestUnion) error { // check put overlap keys := make(map[string]struct{}) @@ -218,7 +219,7 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error { } key := string(preq.Key) if _, ok := keys[key]; ok { - return ErrDuplicateKey + return rpctypes.ErrDuplicateKey } keys[key] = struct{}{} } @@ -248,14 +249,14 @@ func checkRequestDupKeys(reqs []*pb.RequestUnion) error { key := string(dreq.Key) if dreq.RangeEnd == nil { if _, found := keys[key]; found { - return ErrDuplicateKey + return rpctypes.ErrDuplicateKey } } else { lo := sort.SearchStrings(sortedKeys, key) hi := sort.SearchStrings(sortedKeys, string(dreq.RangeEnd)) if lo != hi { // element between lo and hi => overlap - return ErrDuplicateKey + return rpctypes.ErrDuplicateKey } } } @@ -288,14 +289,14 @@ func checkRequestUnion(u *pb.RequestUnion) error { func togRPCError(err error) error { switch err { case storage.ErrCompacted: - return ErrCompacted + return rpctypes.ErrCompacted case storage.ErrFutureRev: - return ErrFutureRev + return rpctypes.ErrFutureRev case lease.ErrLeaseNotFound: - return ErrLeaseNotFound + return rpctypes.ErrLeaseNotFound // TODO: handle error from raft and timeout case etcdserver.ErrRequestTooLarge: - return ErrRequestTooLarge + return rpctypes.ErrRequestTooLarge default: return grpc.Errorf(codes.Internal, err.Error()) } diff --git a/etcdserver/api/v3rpc/lease.go b/etcdserver/api/v3rpc/lease.go index 5e2aedfaf..73e2765dd 100644 --- a/etcdserver/api/v3rpc/lease.go +++ b/etcdserver/api/v3rpc/lease.go @@ -19,6 +19,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/lease" ) @@ -34,7 +35,7 @@ func NewLeaseServer(le etcdserver.Lessor) pb.LeaseServer { func (ls *LeaseServer) LeaseCreate(ctx context.Context, cr *pb.LeaseCreateRequest) (*pb.LeaseCreateResponse, error) { resp, err := ls.le.LeaseCreate(ctx, cr) if err == lease.ErrLeaseExists { - return nil, ErrLeaseExist + return nil, rpctypes.ErrLeaseExist } return resp, err } @@ -42,7 +43,7 @@ func (ls *LeaseServer) LeaseCreate(ctx context.Context, cr *pb.LeaseCreateReques func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { r, err := ls.le.LeaseRevoke(ctx, rr) if err != nil { - return nil, ErrLeaseNotFound + return nil, rpctypes.ErrLeaseNotFound } return r, nil } @@ -59,7 +60,7 @@ func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) erro ttl, err := ls.le.LeaseRenew(lease.LeaseID(req.ID)) if err == lease.ErrLeaseNotFound { - return ErrLeaseNotFound + return rpctypes.ErrLeaseNotFound } if err != nil && err != lease.ErrLeaseNotFound { diff --git a/etcdserver/api/v3rpc/member.go b/etcdserver/api/v3rpc/member.go index 592f021f1..44c38b08e 100644 --- a/etcdserver/api/v3rpc/member.go +++ b/etcdserver/api/v3rpc/member.go @@ -21,6 +21,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc" "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc/codes" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/pkg/types" ) @@ -42,7 +43,7 @@ func NewClusterServer(s *etcdserver.EtcdServer) *ClusterServer { func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) { urls, err := types.NewURLs(r.PeerURLs) if err != nil { - return nil, ErrMemberBadURLs + return nil, rpctypes.ErrMemberBadURLs } now := time.Now() @@ -50,9 +51,9 @@ func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) err = cs.server.AddMember(ctx, *m) switch { case err == etcdserver.ErrIDExists: - return nil, ErrMemberExist + return nil, rpctypes.ErrMemberExist case err == etcdserver.ErrPeerURLexists: - return nil, ErrPeerURLExist + return nil, rpctypes.ErrPeerURLExist case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) } @@ -69,7 +70,7 @@ func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveReq case err == etcdserver.ErrIDRemoved: fallthrough case err == etcdserver.ErrIDNotFound: - return nil, ErrMemberNotFound + return nil, rpctypes.ErrMemberNotFound case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) } @@ -85,9 +86,9 @@ func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateReq err := cs.server.UpdateMember(ctx, m) switch { case err == etcdserver.ErrPeerURLexists: - return nil, ErrPeerURLExist + return nil, rpctypes.ErrPeerURLExist case err == etcdserver.ErrIDNotFound: - return nil, ErrMemberNotFound + return nil, rpctypes.ErrMemberNotFound case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) } diff --git a/etcdserver/api/v3rpc/error.go b/etcdserver/api/v3rpc/rpctypes/error.go similarity index 87% rename from etcdserver/api/v3rpc/error.go rename to etcdserver/api/v3rpc/rpctypes/error.go index 41cbb7e13..cf7d89d2c 100644 --- a/etcdserver/api/v3rpc/error.go +++ b/etcdserver/api/v3rpc/rpctypes/error.go @@ -12,20 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v3rpc +package rpctypes import ( "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc" "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc/codes" - "github.com/coreos/etcd/storage" ) var ( ErrEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided") ErrTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request") ErrDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request") - ErrCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: "+storage.ErrCompacted.Error()) - ErrFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: "+storage.ErrFutureRev.Error()) + ErrCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: storage: required revision has been compacted") + ErrFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: storage: required revision is a future revision") ErrLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found") ErrLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists") diff --git a/integration/v3_grpc_test.go b/integration/v3_grpc_test.go index 5cb502573..133dc3c40 100644 --- a/integration/v3_grpc_test.go +++ b/integration/v3_grpc_test.go @@ -22,6 +22,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc" "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/pkg/testutil" ) @@ -130,8 +131,8 @@ func TestV3TxnTooManyOps(t *testing.T) { } _, err := kvc.Txn(context.Background(), txn) - if err != v3rpc.ErrTooManyOps { - t.Errorf("#%d: err = %v, want %v", i, err, v3rpc.ErrTooManyOps) + if err != rpctypes.ErrTooManyOps { + t.Errorf("#%d: err = %v, want %v", i, err, rpctypes.ErrTooManyOps) } } } @@ -170,17 +171,17 @@ func TestV3TxnDuplicateKeys(t *testing.T) { { txnSuccess: []*pb.RequestUnion{putreq, putreq}, - werr: v3rpc.ErrDuplicateKey, + werr: rpctypes.ErrDuplicateKey, }, { txnSuccess: []*pb.RequestUnion{putreq, delKeyReq}, - werr: v3rpc.ErrDuplicateKey, + werr: rpctypes.ErrDuplicateKey, }, { txnSuccess: []*pb.RequestUnion{putreq, delInRangeReq}, - werr: v3rpc.ErrDuplicateKey, + werr: rpctypes.ErrDuplicateKey, }, { txnSuccess: []*pb.RequestUnion{delKeyReq, delInRangeReq, delKeyReq, delInRangeReq}, @@ -401,15 +402,15 @@ func TestV3TxnInvaildRange(t *testing.T) { Request: &pb.RequestUnion_RequestRange{ RequestRange: rreq}}) - if _, err := kvc.Txn(context.TODO(), txn); err != v3rpc.ErrFutureRev { - t.Errorf("err = %v, want %v", err, v3rpc.ErrFutureRev) + if _, err := kvc.Txn(context.TODO(), txn); err != rpctypes.ErrFutureRev { + t.Errorf("err = %v, want %v", err, rpctypes.ErrFutureRev) } // compacted rev tv, _ := txn.Success[1].Request.(*pb.RequestUnion_RequestRange) tv.RequestRange.Revision = 1 - if _, err := kvc.Txn(context.TODO(), txn); err != v3rpc.ErrCompacted { - t.Errorf("err = %v, want %v", err, v3rpc.ErrCompacted) + if _, err := kvc.Txn(context.TODO(), txn); err != rpctypes.ErrCompacted { + t.Errorf("err = %v, want %v", err, rpctypes.ErrCompacted) } } @@ -426,8 +427,8 @@ func TestV3TooLargeRequest(t *testing.T) { preq := &pb.PutRequest{Key: []byte("foo"), Value: largeV} _, err := kvc.Put(context.Background(), preq) - if err != v3rpc.ErrRequestTooLarge { - t.Errorf("err = %v, want %v", err, v3rpc.ErrRequestTooLarge) + if err != rpctypes.ErrRequestTooLarge { + t.Errorf("err = %v, want %v", err, rpctypes.ErrRequestTooLarge) } } diff --git a/integration/v3_lease_test.go b/integration/v3_lease_test.go index 31672868d..808ff34d3 100644 --- a/integration/v3_lease_test.go +++ b/integration/v3_lease_test.go @@ -19,7 +19,7 @@ import ( "time" "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" - "github.com/coreos/etcd/etcdserver/api/v3rpc" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/pkg/testutil" "github.com/coreos/etcd/storage/storagepb" @@ -105,7 +105,7 @@ func TestV3LeaseCreateByID(t *testing.T) { lresp, err = toGRPC(clus.RandClient()).Lease.LeaseCreate( context.TODO(), &pb.LeaseCreateRequest{ID: 1, TTL: 1}) - if err != v3rpc.ErrLeaseExist { + if err != rpctypes.ErrLeaseExist { t.Error(err) } @@ -241,8 +241,8 @@ func TestV3PutOnNonExistLease(t *testing.T) { badLeaseID := int64(0x12345678) putr := &pb.PutRequest{Key: []byte("foo"), Value: []byte("bar"), Lease: badLeaseID} _, err := toGRPC(clus.RandClient()).KV.Put(ctx, putr) - if err != v3rpc.ErrLeaseNotFound { - t.Errorf("err = %v, want %v", err, v3rpc.ErrCompacted) + if err != rpctypes.ErrLeaseNotFound { + t.Errorf("err = %v, want %v", err, rpctypes.ErrCompacted) } } @@ -364,7 +364,7 @@ func leaseExist(t *testing.T, clus *ClusterV3, leaseID int64) bool { return false } - if err == v3rpc.ErrLeaseExist { + if err == rpctypes.ErrLeaseExist { return true } t.Fatalf("unexpecter error %v", err) From a001651bc1ce0e632bc9dd9ff6b783c7203358a9 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Thu, 17 Mar 2016 11:30:16 -0700 Subject: [PATCH 3/3] clientv3: remove dependency on lease package --- clientv3/concurrency/session.go | 7 +++---- clientv3/example_lease_test.go | 15 +++++++-------- clientv3/integration/kv_test.go | 9 ++++----- clientv3/integration/lease_test.go | 13 ++++++------- clientv3/lease.go | 30 ++++++++++++++++-------------- clientv3/op.go | 5 ++--- contrib/recipes/key.go | 11 +++++------ etcdctlv3/command/lease_command.go | 6 +++--- etcdctlv3/command/put_command.go | 3 +-- 9 files changed, 47 insertions(+), 52 deletions(-) diff --git a/clientv3/concurrency/session.go b/clientv3/concurrency/session.go index 205c14e28..b222d6f4d 100644 --- a/clientv3/concurrency/session.go +++ b/clientv3/concurrency/session.go @@ -18,7 +18,6 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" v3 "github.com/coreos/etcd/clientv3" - "github.com/coreos/etcd/lease" ) // only keep one ephemeral lease per client @@ -35,7 +34,7 @@ type clientSessionMgr struct { // Fault-tolerant applications may use sessions to reason about liveness. type Session struct { client *v3.Client - id lease.LeaseID + id v3.LeaseID cancel context.CancelFunc donec <-chan struct{} @@ -53,7 +52,7 @@ func NewSession(client *v3.Client) (*Session, error) { if err != nil { return nil, err } - id := lease.LeaseID(resp.ID) + id := v3.LeaseID(resp.ID) ctx, cancel := context.WithCancel(client.Ctx()) keepAlive, err := client.KeepAlive(ctx, id) @@ -82,7 +81,7 @@ func NewSession(client *v3.Client) (*Session, error) { } // Lease is the lease ID for keys bound to the session. -func (s *Session) Lease() lease.LeaseID { return s.id } +func (s *Session) Lease() v3.LeaseID { return s.id } // Done returns a channel that closes when the lease is orphaned, expires, or // is otherwise no longer being refreshed. diff --git a/clientv3/example_lease_test.go b/clientv3/example_lease_test.go index 62c63a46d..000606cf2 100644 --- a/clientv3/example_lease_test.go +++ b/clientv3/example_lease_test.go @@ -20,7 +20,6 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" - "github.com/coreos/etcd/lease" ) func ExampleLease_create() { @@ -40,7 +39,7 @@ func ExampleLease_create() { } // after 5 seconds, the key 'foo' will be removed - _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) + _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } @@ -61,13 +60,13 @@ func ExampleLease_revoke() { log.Fatal(err) } - _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) + _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // revoking lease expires the key attached to its lease ID - _, err = cli.Revoke(context.TODO(), lease.LeaseID(resp.ID)) + _, err = cli.Revoke(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) } @@ -95,13 +94,13 @@ func ExampleLease_keepAlive() { log.Fatal(err) } - _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) + _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // the key 'foo' will be kept forever - _, err = cli.KeepAlive(context.TODO(), lease.LeaseID(resp.ID)) + _, err = cli.KeepAlive(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) } @@ -122,13 +121,13 @@ func ExampleLease_keepAliveOnce() { log.Fatal(err) } - _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) + _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // to renew the lease only once - _, err = cli.KeepAliveOnce(context.TODO(), lease.LeaseID(resp.ID)) + _, err = cli.KeepAliveOnce(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) } diff --git a/clientv3/integration/kv_test.go b/clientv3/integration/kv_test.go index 85a3cef1f..c6c4363d0 100644 --- a/clientv3/integration/kv_test.go +++ b/clientv3/integration/kv_test.go @@ -24,7 +24,6 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/integration" - "github.com/coreos/etcd/lease" "github.com/coreos/etcd/pkg/testutil" "github.com/coreos/etcd/storage/storagepb" ) @@ -48,10 +47,10 @@ func TestKVPut(t *testing.T) { tests := []struct { key, val string - leaseID lease.LeaseID + leaseID clientv3.LeaseID }{ - {"foo", "bar", lease.NoLease}, - {"hello", "world", lease.LeaseID(resp.ID)}, + {"foo", "bar", clientv3.NoLease}, + {"hello", "world", clientv3.LeaseID(resp.ID)}, } for i, tt := range tests { @@ -68,7 +67,7 @@ func TestKVPut(t *testing.T) { if !bytes.Equal([]byte(tt.val), resp.Kvs[0].Value) { t.Errorf("#%d: val = %s, want %s", i, tt.val, resp.Kvs[0].Value) } - if tt.leaseID != lease.LeaseID(resp.Kvs[0].Lease) { + if tt.leaseID != clientv3.LeaseID(resp.Kvs[0].Lease) { t.Errorf("#%d: val = %d, want %d", i, tt.leaseID, resp.Kvs[0].Lease) } } diff --git a/clientv3/integration/lease_test.go b/clientv3/integration/lease_test.go index 76a3b6452..dd71e8cc1 100644 --- a/clientv3/integration/lease_test.go +++ b/clientv3/integration/lease_test.go @@ -22,7 +22,6 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/integration" - "github.com/coreos/etcd/lease" "github.com/coreos/etcd/pkg/testutil" ) @@ -42,7 +41,7 @@ func TestLeaseCreate(t *testing.T) { t.Errorf("failed to create lease %v", err) } - _, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) + _, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { t.Fatalf("failed to create key with lease %v", err) } @@ -64,12 +63,12 @@ func TestLeaseRevoke(t *testing.T) { t.Errorf("failed to create lease %v", err) } - _, err = lapi.Revoke(context.Background(), lease.LeaseID(resp.ID)) + _, err = lapi.Revoke(context.Background(), clientv3.LeaseID(resp.ID)) if err != nil { t.Errorf("failed to revoke lease %v", err) } - _, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(lease.LeaseID(resp.ID))) + _, err = kv.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != rpctypes.ErrLeaseNotFound { t.Fatalf("err = %v, want %v", err, rpctypes.ErrLeaseNotFound) } @@ -89,7 +88,7 @@ func TestLeaseKeepAliveOnce(t *testing.T) { t.Errorf("failed to create lease %v", err) } - _, err = lapi.KeepAliveOnce(context.Background(), lease.LeaseID(resp.ID)) + _, err = lapi.KeepAliveOnce(context.Background(), clientv3.LeaseID(resp.ID)) if err != nil { t.Errorf("failed to keepalive lease %v", err) } @@ -108,7 +107,7 @@ func TestLeaseKeepAlive(t *testing.T) { t.Errorf("failed to create lease %v", err) } - rc, kerr := lapi.KeepAlive(context.Background(), lease.LeaseID(resp.ID)) + rc, kerr := lapi.KeepAlive(context.Background(), clientv3.LeaseID(resp.ID)) if kerr != nil { t.Errorf("failed to keepalive lease %v", kerr) } @@ -148,7 +147,7 @@ func TestLeaseKeepAliveHandleFailure(t *testing.T) { t.Errorf("failed to create lease %v", err) } - rc, kerr := lapi.KeepAlive(context.Background(), lease.LeaseID(resp.ID)) + rc, kerr := lapi.KeepAlive(context.Background(), clientv3.LeaseID(resp.ID)) if kerr != nil { t.Errorf("failed to keepalive lease %v", kerr) } diff --git a/clientv3/lease.go b/clientv3/lease.go index c88384781..bcbd8ca16 100644 --- a/clientv3/lease.go +++ b/clientv3/lease.go @@ -21,18 +21,20 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/lease" ) type ( LeaseCreateResponse pb.LeaseCreateResponse LeaseRevokeResponse pb.LeaseRevokeResponse LeaseKeepAliveResponse pb.LeaseKeepAliveResponse + LeaseID int64 ) const ( // a small buffer to store unsent lease responses. leaseResponseChSize = 16 + // NoLease is a lease ID for the absence of a lease. + NoLease LeaseID = 0 ) type Lease interface { @@ -40,14 +42,14 @@ type Lease interface { Create(ctx context.Context, ttl int64) (*LeaseCreateResponse, error) // Revoke revokes the given lease. - Revoke(ctx context.Context, id lease.LeaseID) (*LeaseRevokeResponse, error) + Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) // KeepAlive keeps the given lease alive forever. - KeepAlive(ctx context.Context, id lease.LeaseID) (<-chan *LeaseKeepAliveResponse, error) + KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) // KeepAliveOnce renews the lease once. In most of the cases, Keepalive // should be used instead of KeepAliveOnce. - KeepAliveOnce(ctx context.Context, id lease.LeaseID) (*LeaseKeepAliveResponse, error) + KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) // Close releases all resources Lease keeps for efficient communication // with the etcd server. @@ -71,7 +73,7 @@ type lessor struct { stopCtx context.Context stopCancel context.CancelFunc - keepAlives map[lease.LeaseID]*keepAlive + keepAlives map[LeaseID]*keepAlive } // keepAlive multiplexes a keepalive for a lease over multiple channels @@ -90,7 +92,7 @@ func NewLease(c *Client) Lease { conn: c.ActiveConnection(), donec: make(chan struct{}), - keepAlives: make(map[lease.LeaseID]*keepAlive), + keepAlives: make(map[LeaseID]*keepAlive), } l.remote = pb.NewLeaseClient(l.conn) @@ -121,7 +123,7 @@ func (l *lessor) Create(ctx context.Context, ttl int64) (*LeaseCreateResponse, e } } -func (l *lessor) Revoke(ctx context.Context, id lease.LeaseID) (*LeaseRevokeResponse, error) { +func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) { cctx, cancel := context.WithCancel(ctx) done := cancelWhenStop(cancel, l.stopCtx.Done()) defer close(done) @@ -143,7 +145,7 @@ func (l *lessor) Revoke(ctx context.Context, id lease.LeaseID) (*LeaseRevokeResp } } -func (l *lessor) KeepAlive(ctx context.Context, id lease.LeaseID) (<-chan *LeaseKeepAliveResponse, error) { +func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) { ch := make(chan *LeaseKeepAliveResponse, leaseResponseChSize) l.mu.Lock() @@ -169,7 +171,7 @@ func (l *lessor) KeepAlive(ctx context.Context, id lease.LeaseID) (<-chan *Lease return ch, nil } -func (l *lessor) KeepAliveOnce(ctx context.Context, id lease.LeaseID) (*LeaseKeepAliveResponse, error) { +func (l *lessor) KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) { cctx, cancel := context.WithCancel(ctx) done := cancelWhenStop(cancel, l.stopCtx.Done()) defer close(done) @@ -193,7 +195,7 @@ func (l *lessor) Close() error { return nil } -func (l *lessor) keepAliveCtxCloser(id lease.LeaseID, ctx context.Context, donec <-chan struct{}) { +func (l *lessor) keepAliveCtxCloser(id LeaseID, ctx context.Context, donec <-chan struct{}) { select { case <-donec: return @@ -225,7 +227,7 @@ func (l *lessor) keepAliveCtxCloser(id lease.LeaseID, ctx context.Context, donec } } -func (l *lessor) keepAliveOnce(ctx context.Context, id lease.LeaseID) (*LeaseKeepAliveResponse, error) { +func (l *lessor) keepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) { stream, err := l.getRemote().LeaseKeepAlive(ctx) if err != nil { return nil, err @@ -251,7 +253,7 @@ func (l *lessor) recvKeepAliveLoop() { for _, ka := range l.keepAlives { ka.Close() } - l.keepAlives = make(map[lease.LeaseID]*keepAlive) + l.keepAlives = make(map[LeaseID]*keepAlive) l.mu.Unlock() }() @@ -281,7 +283,7 @@ func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) { // recvKeepAlive updates a lease based on its LeaseKeepAliveResponse func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) { - id := lease.LeaseID(resp.ID) + id := LeaseID(resp.ID) l.mu.Lock() defer l.mu.Unlock() @@ -320,7 +322,7 @@ func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) { return } - tosend := make([]lease.LeaseID, 0) + tosend := make([]LeaseID, 0) now := time.Now() l.mu.Lock() diff --git a/clientv3/op.go b/clientv3/op.go index 0f20db5df..0af89dfc2 100644 --- a/clientv3/op.go +++ b/clientv3/op.go @@ -16,7 +16,6 @@ package clientv3 import ( pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/lease" ) type opType int @@ -51,7 +50,7 @@ type Op struct { // for put val []byte - leaseID lease.LeaseID + leaseID LeaseID } func (op Op) toRequestUnion() *pb.RequestUnion { @@ -146,7 +145,7 @@ func (op *Op) applyOpts(opts []OpOption) { type OpOption func(*Op) // WithLease attaches a lease ID to a key in 'Put' request. -func WithLease(leaseID lease.LeaseID) OpOption { +func WithLease(leaseID LeaseID) OpOption { return func(op *Op) { op.leaseID = leaseID } } diff --git a/contrib/recipes/key.go b/contrib/recipes/key.go index b58d7f2bb..b726a0320 100644 --- a/contrib/recipes/key.go +++ b/contrib/recipes/key.go @@ -22,7 +22,6 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" v3 "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3/concurrency" - "github.com/coreos/etcd/lease" ) // Key is a key/revision pair created by the client and stored on etcd @@ -33,11 +32,11 @@ type RemoteKV struct { val string } -func NewKey(kv v3.KV, key string, leaseID lease.LeaseID) (*RemoteKV, error) { +func NewKey(kv v3.KV, key string, leaseID v3.LeaseID) (*RemoteKV, error) { return NewKV(kv, key, "", leaseID) } -func NewKV(kv v3.KV, key, val string, leaseID lease.LeaseID) (*RemoteKV, error) { +func NewKV(kv v3.KV, key, val string, leaseID v3.LeaseID) (*RemoteKV, error) { rev, err := putNewKV(kv, key, val, leaseID) if err != nil { return nil, err @@ -63,7 +62,7 @@ func NewUniqueKey(kv v3.KV, prefix string) (*RemoteKV, error) { return NewUniqueKV(kv, prefix, "", 0) } -func NewUniqueKV(kv v3.KV, prefix string, val string, leaseID lease.LeaseID) (*RemoteKV, error) { +func NewUniqueKV(kv v3.KV, prefix string, val string, leaseID v3.LeaseID) (*RemoteKV, error) { for { newKey := fmt.Sprintf("%s/%v", prefix, time.Now().UnixNano()) rev, err := putNewKV(kv, newKey, val, 0) @@ -78,7 +77,7 @@ func NewUniqueKV(kv v3.KV, prefix string, val string, leaseID lease.LeaseID) (*R // putNewKV attempts to create the given key, only succeeding if the key did // not yet exist. -func putNewKV(kv v3.KV, key, val string, leaseID lease.LeaseID) (int64, error) { +func putNewKV(kv v3.KV, key, val string, leaseID v3.LeaseID) (int64, error) { cmp := v3.Compare(v3.Version(key), "=", 0) req := v3.OpPut(key, val, v3.WithLease(leaseID)) txnresp, err := kv.Txn(context.TODO()).If(cmp).Then(req).Commit() @@ -98,7 +97,7 @@ func NewSequentialKV(kv v3.KV, prefix, val string) (*RemoteKV, error) { // newSequentialKV allocates a new sequential key /nnnnn with a given // value and lease. Note: a bookkeeping node __ is also allocated. -func newSequentialKV(kv v3.KV, prefix, val string, leaseID lease.LeaseID) (*RemoteKV, error) { +func newSequentialKV(kv v3.KV, prefix, val string, leaseID v3.LeaseID) (*RemoteKV, error) { resp, err := kv.Get(context.TODO(), prefix, v3.WithLastKey()...) if err != nil { return nil, err diff --git a/etcdctlv3/command/lease_command.go b/etcdctlv3/command/lease_command.go index 65dd5f5ee..e50df962e 100644 --- a/etcdctlv3/command/lease_command.go +++ b/etcdctlv3/command/lease_command.go @@ -21,7 +21,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/github.com/spf13/cobra" "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" - "github.com/coreos/etcd/lease" + v3 "github.com/coreos/etcd/clientv3" ) // NewLeaseCommand returns the cobra command for "lease". @@ -92,7 +92,7 @@ func leaseRevokeCommandFunc(cmd *cobra.Command, args []string) { ExitWithError(ExitBadArgs, fmt.Errorf("bad lease ID arg (%v), expecting ID in Hex", err)) } - _, err = mustClientFromCmd(cmd).Revoke(context.TODO(), lease.LeaseID(id)) + _, err = mustClientFromCmd(cmd).Revoke(context.TODO(), v3.LeaseID(id)) if err != nil { fmt.Fprintf(os.Stderr, "failed to revoke lease (%v)\n", err) return @@ -123,7 +123,7 @@ func leaseKeepAliveCommandFunc(cmd *cobra.Command, args []string) { ExitWithError(ExitBadArgs, fmt.Errorf("bad lease ID arg (%v), expecting ID in Hex", err)) } - respc, kerr := mustClientFromCmd(cmd).KeepAlive(context.TODO(), lease.LeaseID(id)) + respc, kerr := mustClientFromCmd(cmd).KeepAlive(context.TODO(), v3.LeaseID(id)) if kerr != nil { ExitWithError(ExitBadConnection, kerr) } diff --git a/etcdctlv3/command/put_command.go b/etcdctlv3/command/put_command.go index eb9e5ca77..9891fbe3f 100644 --- a/etcdctlv3/command/put_command.go +++ b/etcdctlv3/command/put_command.go @@ -22,7 +22,6 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/github.com/spf13/cobra" "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" - "github.com/coreos/etcd/lease" ) var ( @@ -83,7 +82,7 @@ func getPutOp(cmd *cobra.Command, args []string) (string, string, []clientv3.OpO opts := []clientv3.OpOption{} if id != 0 { - opts = append(opts, clientv3.WithLease(lease.LeaseID(id))) + opts = append(opts, clientv3.WithLease(clientv3.LeaseID(id))) } return key, value, opts