From 9e922bde5896c990ff89f5deaeb7512c34bf7dd2 Mon Sep 17 00:00:00 2001 From: Mahak Mukhi Date: Fri, 10 Feb 2017 11:41:20 -0800 Subject: [PATCH] Issue #1060 maximum number of streams on the client should be capped at 100 by default --- test/end2end_test.go | 39 +++++++++++++++++++++++++++++++++++++++ transport/control.go | 5 +++-- transport/http2_client.go | 2 +- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/test/end2end_test.go b/test/end2end_test.go index 902bec42..0ba0256f 100644 --- a/test/end2end_test.go +++ b/test/end2end_test.go @@ -2671,6 +2671,45 @@ func testExceedMaxStreamsLimit(t *testing.T, e env) { } } +const defaultMaxStreamsClient = 100 + +func TestClientExceedMaxStreamsLimit(t *testing.T) { + defer leakCheck(t)() + for _, e := range listTestEnv() { + testExceedMaxStreamsLimit(t, e) + } +} + +func testClientExceedMaxStreamsLimit(t *testing.T, e env) { + te := newTest(t, e) + te.declareLogNoise( + "http2Client.notifyError got notified that the client transport was broken", + "Conn.resetTransport failed to create client transport", + "grpc: the connection is closing", + ) + te.maxStream = 0 // Server allows infinite streams. The cap should be on client side. + te.startServer(&testServer{security: e.security}) + defer te.tearDown() + + cc := te.clientConn() + tc := testpb.NewTestServiceClient(cc) + + // Create as many streams as a client can. + for i := 0; i < defaultMaxStreamsClient; i++ { + if _, err := tc.StreamingInputCall(te.ctx); err != nil { + t.Fatalf("%v.StreamingInputCall(_) = _, %v, want _, ", tc, err) + } + } + + // Trying to create one more should timeout. + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + _, err := tc.StreamingInputCall(ctx) + if err == nil || grpc.Code(err) != codes.DeadlineExceeded { + t.Fatalf("%v.StreamingInputCall(_) = _, %v, want _, %s", tc, err, codes.DeadlineExceeded) + } +} + func TestStreamsQuotaRecovery(t *testing.T) { defer leakCheck(t)() for _, e := range listTestEnv() { diff --git a/transport/control.go b/transport/control.go index 2586cba4..33de7b60 100644 --- a/transport/control.go +++ b/transport/control.go @@ -44,8 +44,9 @@ const ( // The default value of flow control window size in HTTP2 spec. defaultWindowSize = 65535 // The initial window size for flow control. - initialWindowSize = defaultWindowSize // for an RPC - initialConnWindowSize = defaultWindowSize * 16 // for a connection + initialWindowSize = defaultWindowSize // for an RPC + initialConnWindowSize = defaultWindowSize * 16 // for a connection + defaultMaxStreamsClient = 100 ) // The following defines various control items which could flow through diff --git a/transport/http2_client.go b/transport/http2_client.go index 892f8ba6..a85552be 100644 --- a/transport/http2_client.go +++ b/transport/http2_client.go @@ -208,7 +208,7 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) ( state: reachable, activeStreams: make(map[uint32]*Stream), creds: opts.PerRPCCredentials, - maxStreams: math.MaxInt32, + maxStreams: defaultMaxStreamsClient, streamSendQuota: defaultWindowSize, statsHandler: opts.StatsHandler, }