소스 검색

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 년 전
부모
커밋
e0bcd4d516
1개의 변경된 파일11개의 추가작업 그리고 0개의 파일을 삭제
  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