From e179225f2869f14e591ce16d5c76c35ca6741551 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Wed, 4 Jan 2017 16:23:27 -0800 Subject: [PATCH] grpcproxy: tear down watch when client context is done If client closes but all watch streams are not canceled, the outstanding watch will wait until it is canceled, causing watch server to potentially wait forever to close. Fixes #7102 --- proxy/grpcproxy/watch.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/proxy/grpcproxy/watch.go b/proxy/grpcproxy/watch.go index 2c070b31c..42d196ca2 100644 --- a/proxy/grpcproxy/watch.go +++ b/proxy/grpcproxy/watch.go @@ -122,23 +122,23 @@ func (wp *watchProxy) Watch(stream pb.Watch_WatchServer) (err error) { defer func() { stopc <- struct{}{} }() wps.sendLoop() }() - if leaderc != nil { - go func() { - defer func() { stopc <- struct{}{} }() - select { - case <-leaderc: - case <-ctx.Done(): - } - }() - } + // tear down watch if leader goes down or entire watch proxy is terminated + go func() { + defer func() { stopc <- struct{}{} }() + select { + case <-leaderc: + case <-ctx.Done(): + case <-wp.ctx.Done(): + } + }() <-stopc + cancel() + // recv/send may only shutdown after function exits; // goroutine notifies proxy that stream is through go func() { - if leaderc != nil { - <-stopc - } + <-stopc <-stopc wps.close() wp.wg.Done()