From 29a6fd65adc049ffe4374a760fb601c67b5f9e97 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Fri, 17 Feb 2017 12:59:16 -0800 Subject: [PATCH] grpcproxy: only return ctx error in chan stream if recvc is empty Since select{} won't prioritize, ctx.Done() can sometimes override a pending message on recvc. Loop if recvc has messages instead. Fixes #7340 --- proxy/grpcproxy/chan_stream.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/proxy/grpcproxy/chan_stream.go b/proxy/grpcproxy/chan_stream.go index 6a15b22ad6a..b1620bb05ec 100644 --- a/proxy/grpcproxy/chan_stream.go +++ b/proxy/grpcproxy/chan_stream.go @@ -116,17 +116,23 @@ func (s *chanStream) SendMsg(m interface{}) error { func (s *chanStream) RecvMsg(m interface{}) error { v := m.(*interface{}) - select { - case msg, ok := <-s.recvc: - if !ok { - return grpc.ErrClientConnClosing + for { + select { + case msg, ok := <-s.recvc: + if !ok { + return grpc.ErrClientConnClosing + } + if err, ok := msg.(error); ok { + return err + } + *v = msg + return nil + case <-s.ctx.Done(): } - if err, ok := msg.(error); ok { - return err + if len(s.recvc) == 0 { + // prioritize any pending recv messages over canceled context + break } - *v = msg - return nil - case <-s.ctx.Done(): } return s.ctx.Err() }