From e0bcd4d5161435082aa3aecbb6cff94b1038a911 Mon Sep 17 00:00:00 2001 From: Denys Smirnov Date: Mon, 5 Dec 2016 19:22:15 +0200 Subject: [PATCH] clientv3: return error from KeepAlive if corresponding loop exits after recvKeepAliveLoop exits client might call KeepAlive adding request channel that will not be closed this fix makes sure that recvKeepAliveLoop is running before adding request to lessor's list and returns error otherwise Fixes #6922 --- clientv3/lease.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/clientv3/lease.go b/clientv3/lease.go index d3b587e8f..987961f85 100644 --- a/clientv3/lease.go +++ b/clientv3/lease.go @@ -15,6 +15,7 @@ package clientv3 import ( + "errors" "sync" "time" @@ -69,6 +70,8 @@ const ( NoLease LeaseID = 0 ) +var ErrLeaseHalted = errors.New("etcdclient: leases halted") + type Lease interface { // Grant creates a new lease. Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) @@ -216,6 +219,14 @@ func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAl ch := make(chan *LeaseKeepAliveResponse, leaseResponseChSize) l.mu.Lock() + // ensure that recvKeepAliveLoop is still running + select { + case <-l.donec: + l.mu.Unlock() + close(ch) + return ch, ErrLeaseHalted + default: + } ka, ok := l.keepAlives[id] if !ok { // create fresh keep alive