Merge pull request #5197 from heyitsanthony/fix-lease-revoke-keepalive

etcdserver: respond with ttl=0 for revoked lease keep alive
release-3.0
Anthony Romano 2016-04-26 14:13:54 -07:00
commit ce76c28805
3 changed files with 52 additions and 2 deletions

View File

@ -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:
}
}
}

View File

@ -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) {

View File

@ -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
}