From 9a20743190a796b6e22184d88936dbe8ff7cb056 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Thu, 17 Nov 2016 14:59:06 -0800 Subject: [PATCH] v3rpc: don't close watcher if client closes send grpc-gateway will CloseSend but still want to receive updates. --- etcdserver/api/v3rpc/watch.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/etcdserver/api/v3rpc/watch.go b/etcdserver/api/v3rpc/watch.go index c7fb97b6d..f0215531d 100644 --- a/etcdserver/api/v3rpc/watch.go +++ b/etcdserver/api/v3rpc/watch.go @@ -131,10 +131,14 @@ func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) { // but when stream.Context().Done() is closed, the stream's recv // may continue to block since it uses a different context, leading to // deadlock when calling sws.close(). - go func() { errc <- sws.recvLoop() }() - + go func() { + if rerr := sws.recvLoop(); rerr != nil { + errc <- rerr + } + }() select { case err = <-errc: + close(sws.ctrlStream) case <-stream.Context().Done(): err = stream.Context().Err() // the only server-side cancellation is noleader for now. @@ -147,7 +151,6 @@ func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) { } func (sws *serverWatchStream) recvLoop() error { - defer close(sws.ctrlStream) for { req, err := sws.gRPCStream.Recv() if err == io.EOF {