From b25edb62cc1cb49b82760084a5dbe4e6d5a5c4d1 Mon Sep 17 00:00:00 2001 From: "Sahdev P. Zala" Date: Sun, 20 Jan 2019 11:39:28 -0500 Subject: [PATCH] clientV3watch: Watch Close should close successfully Closing of watch by client will cancel the watch grpc stream and can produce a context canceled error. However, since client simply wanted to close the watcher the error can create confusion that something went wrong instead of a successful close. Ensure that Close do not return error. Fixed #10340 --- clientv3/integration/watch_test.go | 21 +++++++++++++++++++++ clientv3/watch.go | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/clientv3/integration/watch_test.go b/clientv3/integration/watch_test.go index 3482f31bd..bf751d679 100644 --- a/clientv3/integration/watch_test.go +++ b/clientv3/integration/watch_test.go @@ -1133,3 +1133,24 @@ func TestWatchCancelDisconnected(t *testing.T) { t.Fatal("took too long to cancel disconnected watcher") } } + +// TestWatchClose ensures that close does not return error +func TestWatchClose(t *testing.T) { + runWatchTest(t, testWatchClose) +} + +func testWatchClose(t *testing.T, wctx *watchctx) { + ctx, cancel := context.WithCancel(context.Background()) + wch := wctx.w.Watch(ctx, "a") + cancel() + if wch == nil { + t.Fatalf("expected watcher channel, got nil") + } + if wctx.w.Close() != nil { + t.Fatalf("watch did not close successfully") + } + wresp, ok := <-wch + if ok { + t.Fatalf("read wch got %v; expected closed channel", wresp) + } +} diff --git a/clientv3/watch.go b/clientv3/watch.go index 8ec58bb14..d50acbca3 100644 --- a/clientv3/watch.go +++ b/clientv3/watch.go @@ -371,6 +371,10 @@ func (w *watcher) Close() (err error) { err = werr } } + // Consider context.Canceled as a successful close + if err == context.Canceled { + err = nil + } return err }