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)