Browse Source

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
Denys Smirnov 9 years ago
parent
commit
e0bcd4d516
1 changed files with 11 additions and 0 deletions
  1. 11 0
      clientv3/lease.go

+ 11 - 0
clientv3/lease.go

@@ -15,6 +15,7 @@
 package clientv3
 package clientv3
 
 
 import (
 import (
+	"errors"
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
@@ -69,6 +70,8 @@ const (
 	NoLease LeaseID = 0
 	NoLease LeaseID = 0
 )
 )
 
 
+var ErrLeaseHalted = errors.New("etcdclient: leases halted")
+
 type Lease interface {
 type Lease interface {
 	// Grant creates a new lease.
 	// Grant creates a new lease.
 	Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error)
 	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)
 	ch := make(chan *LeaseKeepAliveResponse, leaseResponseChSize)
 
 
 	l.mu.Lock()
 	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]
 	ka, ok := l.keepAlives[id]
 	if !ok {
 	if !ok {
 		// create fresh keep alive
 		// create fresh keep alive