From 953dc60d01d46e726227e9cf2c4e6433ae16dd36 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Thu, 18 Aug 2016 16:07:04 -0700 Subject: [PATCH] clientconn: return ctx.Err() on getTransport failure if non-nil Otherwise, closing the client with FailFast=false causes outstanding RPCs to spin forever. --- call_test.go | 16 ++++++++++++++++ clientconn.go | 3 +++ 2 files changed, 19 insertions(+) diff --git a/call_test.go b/call_test.go index 97eb9c002a96..edffef2bbb27 100644 --- a/call_test.go +++ b/call_test.go @@ -276,3 +276,19 @@ func TestInvokeCancel(t *testing.T) { cc.Close() server.stop() } + +// TestInvokeCancelClosedNoFail checks that a canceled Invoke with FailFast=false +// on a closed client will terminate. +func TestInvokeCancelClosedNoFailFast(t *testing.T) { + server, cc := setUp(t, 0, math.MaxUint32) + var reply string + cc.Close() + req := "hello" + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err := Invoke(ctx, "/foo/bar", &req, &reply, cc, FailFast(false)) + if err == nil { + t.Fatalf("canceled invoke on closed connection should fail") + } + server.stop() +} diff --git a/clientconn.go b/clientconn.go index f5bdafb90742..5ee65d3c1e07 100644 --- a/clientconn.go +++ b/clientconn.go @@ -506,6 +506,9 @@ func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) if put != nil { put() } + if ctx.Err() != nil { + return nil, nil, toRPCErr(ctx.Err()) + } return nil, nil, errConnClosing } t, err := ac.wait(ctx, cc.dopts.balancer != nil, !opts.BlockingWait)