From c100e40715c623cbc56012ca957a4b2676870830 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Wed, 12 Oct 2016 15:54:12 -0700 Subject: [PATCH] clientv3: only receive from closing streams in Watcher close Was overcounting the number of expected closing messages; the resuming list may have nil entries. Also the full client wasn't closing the watcher client, only canceling its context, so client closes weren't joining with the watcher shutdown. Fixes #6605 --- clientv3/client.go | 1 + clientv3/watch.go | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clientv3/client.go b/clientv3/client.go index 148addea8..7f7d42770 100644 --- a/clientv3/client.go +++ b/clientv3/client.go @@ -86,6 +86,7 @@ func NewFromConfigFile(path string) (*Client, error) { // Close shuts down the client's etcd connections. func (c *Client) Close() error { c.cancel() + c.Watcher.Close() return toErr(c.ctx, c.conn.Close()) } diff --git a/clientv3/watch.go b/clientv3/watch.go index 1d652c81a..5281f8f5c 100644 --- a/clientv3/watch.go +++ b/clientv3/watch.go @@ -396,15 +396,17 @@ func (w *watchGrpcStream) run() { for _, ws := range w.substreams { if _, ok := closing[ws]; !ok { close(ws.recvc) + closing[ws] = struct{}{} } } for _, ws := range w.resuming { if _, ok := closing[ws]; ws != nil && !ok { close(ws.recvc) + closing[ws] = struct{}{} } } w.joinSubstreams() - for toClose := len(w.substreams) + len(w.resuming); toClose > 0; toClose-- { + for range closing { w.closeSubstream(<-w.closingc) }