From c8405557a448d1792dd75b64c46e34d7fdd15cf7 Mon Sep 17 00:00:00 2001 From: dfawley Date: Wed, 4 Oct 2017 13:57:10 -0700 Subject: [PATCH] Remove Go1.6 support (#1492) --- .travis.yml | 1 - README.md | 2 +- benchmark/benchmark16_test.go | 112 ------------------ ...{benchmark17_test.go => benchmark_test.go} | 0 clientconn.go | 2 +- examples/README.md | 2 +- go16.go | 98 --------------- go17.go | 99 ---------------- naming/go17.go | 2 +- naming/go17_test.go | 2 +- proxy.go | 3 +- rpc_util.go | 53 +++++++++ test/end2end_test.go | 2 +- transport/go16.go | 45 ------- transport/go17.go | 46 ------- transport/http2_client.go | 6 +- transport/transport.go | 12 ++ vet.sh | 1 - 18 files changed, 75 insertions(+), 413 deletions(-) delete mode 100644 benchmark/benchmark16_test.go rename benchmark/{benchmark17_test.go => benchmark_test.go} (100%) delete mode 100644 go16.go delete mode 100644 go17.go delete mode 100644 transport/go16.go delete mode 100644 transport/go17.go diff --git a/.travis.yml b/.travis.yml index 413881a1d..22bf25004 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: go go: - - 1.6.x - 1.7.x - 1.8.x - 1.9.x diff --git a/README.md b/README.md index f1f789cfb..622a5dc3e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ $ go get -u google.golang.org/grpc Prerequisites ------------- -This requires Go 1.6 or later. +This requires Go 1.7 or later. Constraints ----------- diff --git a/benchmark/benchmark16_test.go b/benchmark/benchmark16_test.go deleted file mode 100644 index fc33e80d0..000000000 --- a/benchmark/benchmark16_test.go +++ /dev/null @@ -1,112 +0,0 @@ -// +build go1.6,!go1.7 - -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package benchmark - -import ( - "os" - "testing" - - "google.golang.org/grpc" - "google.golang.org/grpc/benchmark/stats" -) - -func BenchmarkClientStreamc1(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 1, 1, 1, false}) -} - -func BenchmarkClientStreamc8(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 8, 1, 1, false}) -} - -func BenchmarkClientStreamc64(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 64, 1, 1, false}) -} - -func BenchmarkClientStreamc512(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 512, 1, 1, false}) -} -func BenchmarkClientUnaryc1(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 1, 1, 1, false}) -} - -func BenchmarkClientUnaryc8(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 8, 1, 1, false}) -} - -func BenchmarkClientUnaryc64(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 64, 1, 1, false}) -} - -func BenchmarkClientUnaryc512(b *testing.B) { - grpc.EnableTracing = true - runStream(b, stats.Features{"", true, 0, 0, 0, 512, 1, 1, false}) -} - -func BenchmarkClientStreamNoTracec1(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 1, 1, 1, false}) -} - -func BenchmarkClientStreamNoTracec8(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 8, 1, 1, false}) -} - -func BenchmarkClientStreamNoTracec64(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 64, 1, 1, false}) -} - -func BenchmarkClientStreamNoTracec512(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 512, 1, 1, false}) -} -func BenchmarkClientUnaryNoTracec1(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 1, 1, 1, false}) -} - -func BenchmarkClientUnaryNoTracec8(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 8, 1, 1, false}) -} - -func BenchmarkClientUnaryNoTracec64(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 64, 1, 1, false}) -} - -func BenchmarkClientUnaryNoTracec512(b *testing.B) { - grpc.EnableTracing = false - runStream(b, stats.Features{"", false, 0, 0, 0, 512, 1, 1, false}) - runStream(b, stats.Features{"", false, 0, 0, 0, 512, 1, 1, false}) -} - -func TestMain(m *testing.M) { - os.Exit(stats.RunTestMain(m)) -} diff --git a/benchmark/benchmark17_test.go b/benchmark/benchmark_test.go similarity index 100% rename from benchmark/benchmark17_test.go rename to benchmark/benchmark_test.go diff --git a/clientconn.go b/clientconn.go index ae64a6602..a34bd987c 100644 --- a/clientconn.go +++ b/clientconn.go @@ -378,7 +378,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * if cc.dopts.copts.Dialer == nil { cc.dopts.copts.Dialer = newProxyDialer( func(ctx context.Context, addr string) (net.Conn, error) { - return dialContext(ctx, "tcp", addr) + return (&net.Dialer{}).DialContext(ctx, "tcp", addr) }, ) } diff --git a/examples/README.md b/examples/README.md index 27a8a8553..6d9175c68 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,7 +8,7 @@ For this sample, we've already generated the server and client stubs from [hello PREREQUISITES ------------- -- This requires Go 1.5 or later +- This requires Go 1.7 or later - Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) ``` diff --git a/go16.go b/go16.go deleted file mode 100644 index f3dbf2170..000000000 --- a/go16.go +++ /dev/null @@ -1,98 +0,0 @@ -// +build go1.6,!go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "fmt" - "io" - "net" - "net/http" - "os" - - "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address) -} - -func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { - req.Cancel = ctx.Done() - if err := req.Write(conn); err != nil { - return fmt.Errorf("failed to write the HTTP request: %v", err) - } - return nil -} - -// toRPCErr converts an error into an error from the status package. -func toRPCErr(err error) error { - if _, ok := status.FromError(err); ok { - return err - } - switch e := err.(type) { - case transport.StreamError: - return status.Error(e.Code, e.Desc) - case transport.ConnectionError: - return status.Error(codes.Unavailable, e.Desc) - default: - switch err { - case context.DeadlineExceeded: - return status.Error(codes.DeadlineExceeded, err.Error()) - case context.Canceled: - return status.Error(codes.Canceled, err.Error()) - case ErrClientConnClosing: - return status.Error(codes.FailedPrecondition, err.Error()) - } - } - return status.Error(codes.Unknown, err.Error()) -} - -// convertCode converts a standard Go error into its canonical code. Note that -// this is only used to translate the error returned by the server applications. -func convertCode(err error) codes.Code { - switch err { - case nil: - return codes.OK - case io.EOF: - return codes.OutOfRange - case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF: - return codes.FailedPrecondition - case os.ErrInvalid: - return codes.InvalidArgument - case context.Canceled: - return codes.Canceled - case context.DeadlineExceeded: - return codes.DeadlineExceeded - } - switch { - case os.IsExist(err): - return codes.AlreadyExists - case os.IsNotExist(err): - return codes.NotFound - case os.IsPermission(err): - return codes.PermissionDenied - } - return codes.Unknown -} diff --git a/go17.go b/go17.go deleted file mode 100644 index de23098eb..000000000 --- a/go17.go +++ /dev/null @@ -1,99 +0,0 @@ -// +build go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "context" - "fmt" - "io" - "net" - "net/http" - "os" - - netctx "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/grpc/transport" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, network, address) -} - -func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { - req = req.WithContext(ctx) - if err := req.Write(conn); err != nil { - return fmt.Errorf("failed to write the HTTP request: %v", err) - } - return nil -} - -// toRPCErr converts an error into an error from the status package. -func toRPCErr(err error) error { - if _, ok := status.FromError(err); ok { - return err - } - switch e := err.(type) { - case transport.StreamError: - return status.Error(e.Code, e.Desc) - case transport.ConnectionError: - return status.Error(codes.Unavailable, e.Desc) - default: - switch err { - case context.DeadlineExceeded, netctx.DeadlineExceeded: - return status.Error(codes.DeadlineExceeded, err.Error()) - case context.Canceled, netctx.Canceled: - return status.Error(codes.Canceled, err.Error()) - case ErrClientConnClosing: - return status.Error(codes.FailedPrecondition, err.Error()) - } - } - return status.Error(codes.Unknown, err.Error()) -} - -// convertCode converts a standard Go error into its canonical code. Note that -// this is only used to translate the error returned by the server applications. -func convertCode(err error) codes.Code { - switch err { - case nil: - return codes.OK - case io.EOF: - return codes.OutOfRange - case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF: - return codes.FailedPrecondition - case os.ErrInvalid: - return codes.InvalidArgument - case context.Canceled, netctx.Canceled: - return codes.Canceled - case context.DeadlineExceeded, netctx.DeadlineExceeded: - return codes.DeadlineExceeded - } - switch { - case os.IsExist(err): - return codes.AlreadyExists - case os.IsNotExist(err): - return codes.NotFound - case os.IsPermission(err): - return codes.PermissionDenied - } - return codes.Unknown -} diff --git a/naming/go17.go b/naming/go17.go index a537b08c6..8bdf21e79 100644 --- a/naming/go17.go +++ b/naming/go17.go @@ -1,4 +1,4 @@ -// +build go1.6, !go1.8 +// +build go1.7, !go1.8 /* * diff --git a/naming/go17_test.go b/naming/go17_test.go index db39b9ab7..d1de221a5 100644 --- a/naming/go17_test.go +++ b/naming/go17_test.go @@ -1,4 +1,4 @@ -// +build go1.6, !go1.8 +// +build go1.7, !go1.8 /* * diff --git a/proxy.go b/proxy.go index 2d40236e2..3e17efec6 100644 --- a/proxy.go +++ b/proxy.go @@ -82,7 +82,8 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, addr string) (_ Header: map[string][]string{"User-Agent": {grpcUA}}, }) - if err := sendHTTPRequest(ctx, req, conn); err != nil { + req = req.WithContext(ctx) + if err := req.Write(conn); err != nil { return nil, fmt.Errorf("failed to write the HTTP request: %v", err) } diff --git a/rpc_util.go b/rpc_util.go index aa0c6b68c..b80ca66e3 100644 --- a/rpc_util.go +++ b/rpc_util.go @@ -21,10 +21,12 @@ package grpc import ( "bytes" "compress/gzip" + stdctx "context" "encoding/binary" "io" "io/ioutil" "math" + "os" "sync" "time" @@ -410,6 +412,57 @@ func updateRPCInfoInContext(ctx context.Context, s rpcInfo) { return } +// toRPCErr converts an error into an error from the status package. +func toRPCErr(err error) error { + if _, ok := status.FromError(err); ok { + return err + } + switch e := err.(type) { + case transport.StreamError: + return status.Error(e.Code, e.Desc) + case transport.ConnectionError: + return status.Error(codes.Unavailable, e.Desc) + default: + switch err { + case context.DeadlineExceeded, stdctx.DeadlineExceeded: + return status.Error(codes.DeadlineExceeded, err.Error()) + case context.Canceled, stdctx.Canceled: + return status.Error(codes.Canceled, err.Error()) + case ErrClientConnClosing: + return status.Error(codes.FailedPrecondition, err.Error()) + } + } + return status.Error(codes.Unknown, err.Error()) +} + +// convertCode converts a standard Go error into its canonical code. Note that +// this is only used to translate the error returned by the server applications. +func convertCode(err error) codes.Code { + switch err { + case nil: + return codes.OK + case io.EOF: + return codes.OutOfRange + case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF: + return codes.FailedPrecondition + case os.ErrInvalid: + return codes.InvalidArgument + case context.Canceled, stdctx.Canceled: + return codes.Canceled + case context.DeadlineExceeded, stdctx.DeadlineExceeded: + return codes.DeadlineExceeded + } + switch { + case os.IsExist(err): + return codes.AlreadyExists + case os.IsNotExist(err): + return codes.NotFound + case os.IsPermission(err): + return codes.PermissionDenied + } + return codes.Unknown +} + // Code returns the error code for err if it was produced by the rpc system. // Otherwise, it returns codes.Unknown. // diff --git a/test/end2end_test.go b/test/end2end_test.go index 0add563db..ab151209a 100644 --- a/test/end2end_test.go +++ b/test/end2end_test.go @@ -2874,7 +2874,7 @@ func TestRetry(t *testing.T) { defer leakcheck.Check(t) for _, e := range listTestEnv() { if e.name == "handler-tls" { - // In race mode, with go1.6, the test never returns with handler_server. + // Fails with RST_STREAM / FLOW_CONTROL_ERROR continue } testRetry(t, e) diff --git a/transport/go16.go b/transport/go16.go deleted file mode 100644 index 7cffee11e..000000000 --- a/transport/go16.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build go1.6,!go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package transport - -import ( - "net" - - "google.golang.org/grpc/codes" - - "golang.org/x/net/context" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address) -} - -// ContextErr converts the error from context package into a StreamError. -func ContextErr(err error) StreamError { - switch err { - case context.DeadlineExceeded: - return streamErrorf(codes.DeadlineExceeded, "%v", err) - case context.Canceled: - return streamErrorf(codes.Canceled, "%v", err) - } - return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err) -} diff --git a/transport/go17.go b/transport/go17.go deleted file mode 100644 index 2464e69fa..000000000 --- a/transport/go17.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build go1.7 - -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package transport - -import ( - "context" - "net" - - "google.golang.org/grpc/codes" - - netctx "golang.org/x/net/context" -) - -// dialContext connects to the address on the named network. -func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, network, address) -} - -// ContextErr converts the error from context package into a StreamError. -func ContextErr(err error) StreamError { - switch err { - case context.DeadlineExceeded, netctx.DeadlineExceeded: - return streamErrorf(codes.DeadlineExceeded, "%v", err) - case context.Canceled, netctx.Canceled: - return streamErrorf(codes.Canceled, "%v", err) - } - return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err) -} diff --git a/transport/http2_client.go b/transport/http2_client.go index 0b4846fdc..1abb62e6d 100644 --- a/transport/http2_client.go +++ b/transport/http2_client.go @@ -109,7 +109,7 @@ func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error if fn != nil { return fn(ctx, addr) } - return dialContext(ctx, "tcp", addr) + return (&net.Dialer{}).DialContext(ctx, "tcp", addr) } func isTemporary(err error) bool { @@ -148,11 +148,9 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions, t ctx, cancel := context.WithCancel(ctx) connectCtx, connectCancel := context.WithTimeout(ctx, timeout) defer func() { + connectCancel() if err != nil { cancel() - // Don't call connectCancel in success path due to a race in Go 1.6: - // https://github.com/golang/go/issues/15078. - connectCancel() } }() diff --git a/transport/transport.go b/transport/transport.go index e4a354032..bde8fa5c3 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -21,6 +21,7 @@ package transport // import "google.golang.org/grpc/transport" import ( + stdctx "context" "fmt" "io" "net" @@ -718,6 +719,17 @@ func wait(ctx, tctx context.Context, done, goAway <-chan struct{}, proceed <-cha } } +// ContextErr converts the error from context package into a StreamError. +func ContextErr(err error) StreamError { + switch err { + case context.DeadlineExceeded, stdctx.DeadlineExceeded: + return streamErrorf(codes.DeadlineExceeded, "%v", err) + case context.Canceled, stdctx.Canceled: + return streamErrorf(codes.Canceled, "%v", err) + } + return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err) +} + // GoAwayReason contains the reason for the GoAway frame received. type GoAwayReason uint8 diff --git a/vet.sh b/vet.sh index a3e8ef922..9ef48378f 100755 --- a/vet.sh +++ b/vet.sh @@ -63,7 +63,6 @@ trap cleanup EXIT git ls-files "*.go" | xargs sed -i 's:"golang.org/x/net/context":"context":' set +o pipefail # TODO: Stop filtering pb.go files once golang/protobuf#214 is fixed. -# TODO: Remove clientconn exception once go1.6 support is removed. go tool vet -all . 2>&1 | grep -vF '.pb.go:' | tee /dev/stderr | (! read) set -o pipefail git reset --hard HEAD