diff --git a/clientv3/integration/lease_test.go b/clientv3/integration/lease_test.go index 1cbcdaae2..bf32607c3 100644 --- a/clientv3/integration/lease_test.go +++ b/clientv3/integration/lease_test.go @@ -188,3 +188,48 @@ func TestLeaseKeepAliveHandleFailure(t *testing.T) { t.Errorf("chan is not closed, want lease Close() closes chan") } } + +type leaseCh struct { + lid clientv3.LeaseID + ch <-chan *clientv3.LeaseKeepAliveResponse +} + +// TestLeaseKeepAliveNotFound ensures a revoked lease won't stop other keep alives +func TestLeaseKeepAliveNotFound(t *testing.T) { + defer testutil.AfterTest(t) + + clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) + defer clus.Terminate(t) + + cli := clus.RandClient() + lchs := []leaseCh{} + for i := 0; i < 3; i++ { + resp, rerr := cli.Grant(context.TODO(), 5) + if rerr != nil { + t.Fatal(rerr) + } + kach, kaerr := cli.KeepAlive(context.Background(), resp.ID) + if kaerr != nil { + t.Fatal(kaerr) + } + lchs = append(lchs, leaseCh{resp.ID, kach}) + } + + if _, err := cli.Revoke(context.TODO(), lchs[1].lid); err != nil { + t.Fatal(err) + } + + <-lchs[0].ch + if _, ok := <-lchs[0].ch; !ok { + t.Fatalf("closed keepalive on wrong lease") + } + + timec := time.After(5 * time.Second) + for range lchs[1].ch { + select { + case <-timec: + t.Fatalf("revoke did not close keep alive") + default: + } + } +} diff --git a/clientv3/lease.go b/clientv3/lease.go index 00873b02d..3f8edf4ff 100644 --- a/clientv3/lease.go +++ b/clientv3/lease.go @@ -18,6 +18,7 @@ import ( "sync" "time" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" "google.golang.org/grpc" @@ -198,6 +199,9 @@ func (l *lessor) KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAlive for { resp, err := l.keepAliveOnce(cctx, id) if err == nil { + if resp.TTL == 0 { + err = rpctypes.ErrLeaseNotFound + } return resp, err } if isHalted(ctx, err) { diff --git a/etcdserver/api/v3rpc/lease.go b/etcdserver/api/v3rpc/lease.go index b21b1d111..81fd3b6ee 100644 --- a/etcdserver/api/v3rpc/lease.go +++ b/etcdserver/api/v3rpc/lease.go @@ -60,10 +60,11 @@ func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) erro ttl, err := ls.le.LeaseRenew(lease.LeaseID(req.ID)) if err == lease.ErrLeaseNotFound { - return rpctypes.ErrLeaseNotFound + err = nil + ttl = 0 } - if err != nil && err != lease.ErrLeaseNotFound { + if err != nil { return err }