diff --git a/LANGUAGES.md b/LANGUAGES.md index 897494e5b60..cd70b063170 100644 --- a/LANGUAGES.md +++ b/LANGUAGES.md @@ -134,7 +134,7 @@ The Language/Library Levels indicate the minimum and maximum versions that are u Go Yes -1.2.11.8.3 +1.71.9.3 YesYesYes YesYesYes YesYesYesYes diff --git a/build/docker/README.md b/build/docker/README.md index f58e88ba09d..aefc945217a 100644 --- a/build/docker/README.md +++ b/build/docker/README.md @@ -148,7 +148,7 @@ Last updated: October 1, 2017 | delphi | | | | Not in CI | | dotnet | | 2.1.4 | 2.1.4 | v2.1.4 SDK uses v2.0.5 Runtime | | erlang | R16B03 | 18.3 | 20.0.4 | | -| go | 1.2.1 | 1.6.2 | 1.8.3 | | +| go | 1.7.6 | 1.7.6 | 1.8.3 | | | haskell | 7.6.3 | 7.10.3 | 8.0.2 | | | haxe | | 3.2.1 | 3.4.2 | disabled in trusty builds - cores on install v3.0.0, disabled in artful builds - see THRIFT-4352 | | java | 1.7.0_151 | 1.8.0_151 | 1.8.0_151 | | diff --git a/build/docker/ubuntu-trusty/Dockerfile b/build/docker/ubuntu-trusty/Dockerfile index 40f9c55c62a..a8e4d3baa25 100644 --- a/build/docker/ubuntu-trusty/Dockerfile +++ b/build/docker/ubuntu-trusty/Dockerfile @@ -113,9 +113,15 @@ RUN apt-get install -y --no-install-recommends \ `# GlibC dependencies` \ libglib2.0-dev -RUN apt-get install -y --no-install-recommends \ -`# golang (go) dependencies` \ - golang-go +# golang +ENV GOLANG_VERSION 1.7.6 +ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz +ENV GOLANG_DOWNLOAD_SHA256 ad5808bf42b014c22dd7646458f631385003049ded0bb6af2efc7f1f79fa29ea +RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ + echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ + tar -C /usr/local -xzf golang.tar.gz && \ + ln -s /usr/local/go/bin/go /usr/local/bin && \ + rm golang.tar.gz RUN apt-get install -y --no-install-recommends \ `# Haskell dependencies` \ diff --git a/build/docker/ubuntu-xenial/Dockerfile b/build/docker/ubuntu-xenial/Dockerfile index b37434bb7dc..683d7e8640d 100644 --- a/build/docker/ubuntu-xenial/Dockerfile +++ b/build/docker/ubuntu-xenial/Dockerfile @@ -137,10 +137,15 @@ RUN apt-get install -y --no-install-recommends \ `# GlibC dependencies` \ libglib2.0-dev -RUN apt-get install -y --no-install-recommends \ -`# golang (go) dependencies` \ - golang-go \ - golang-race-detector-runtime +# golang +ENV GOLANG_VERSION 1.7.6 +ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz +ENV GOLANG_DOWNLOAD_SHA256 ad5808bf42b014c22dd7646458f631385003049ded0bb6af2efc7f1f79fa29ea +RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \ + echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \ + tar -C /usr/local -xzf golang.tar.gz && \ + ln -s /usr/local/go/bin/go /usr/local/bin && \ + rm golang.tar.gz RUN apt-get install -y --no-install-recommends \ `# Haskell dependencies` \ diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc index 7727118e8c6..fa79a37325e 100644 --- a/compiler/cpp/src/thrift/generate/t_go_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc @@ -81,7 +81,6 @@ class t_go_generator : public t_generator { gen_package_prefix_ = ""; package_flag = ""; read_write_private_ = false; - legacy_context_ = false; ignore_initialisms_ = false; for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { if( iter->first.compare("package_prefix") == 0) { @@ -92,8 +91,6 @@ class t_go_generator : public t_generator { package_flag = (iter->second); } else if( iter->first.compare("read_write_private") == 0) { read_write_private_ = true; - } else if( iter->first.compare("legacy_context") == 0) { - legacy_context_ = true; } else if( iter->first.compare("ignore_initialisms") == 0) { ignore_initialisms_ = true; } else { @@ -287,7 +284,6 @@ class t_go_generator : public t_generator { std::string gen_package_prefix_; std::string gen_thrift_import_; bool read_write_private_; - bool legacy_context_; bool ignore_initialisms_; /** @@ -883,16 +879,10 @@ string t_go_generator::go_imports_begin(bool consts) { "\t\"database/sql/driver\"\n" "\t\"errors\"\n"; } - if (legacy_context_) { - extra += - "\t\"golang.org/x/net/context\"\n"; - } else { - extra += - "\t\"context\"\n"; - } return string( "import (\n" "\t\"bytes\"\n" + "\t\"context\"\n" "\t\"reflect\"\n" + extra + "\t\"fmt\"\n" @@ -2073,9 +2063,6 @@ void t_go_generator::generate_service_remote(t_service* tservice) { string unused_protection; string ctxPackage = "context"; - if (legacy_context_) { - ctxPackage = "golang.org/x/net/context"; - } f_remote << go_autogen_comment(); f_remote << indent() << "package main" << endl << endl; @@ -2576,7 +2563,7 @@ void t_go_generator::generate_service_server(t_service* tservice) { f_types_ << indent() << " oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId)" << endl; f_types_ << indent() << " " << x << ".Write(oprot)" << endl; f_types_ << indent() << " oprot.WriteMessageEnd()" << endl; - f_types_ << indent() << " oprot.Flush()" << endl; + f_types_ << indent() << " oprot.Flush(ctx)" << endl; f_types_ << indent() << " return false, " << x << endl; f_types_ << indent() << "" << endl; f_types_ << indent() << "}" << endl << endl; @@ -2641,7 +2628,7 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* << "\", thrift.EXCEPTION, seqId)" << endl; f_types_ << indent() << " x.Write(oprot)" << endl; f_types_ << indent() << " oprot.WriteMessageEnd()" << endl; - f_types_ << indent() << " oprot.Flush()" << endl; + f_types_ << indent() << " oprot.Flush(ctx)" << endl; } f_types_ << indent() << " return false, err" << endl; f_types_ << indent() << "}" << endl << endl; @@ -2709,7 +2696,7 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* << "\", thrift.EXCEPTION, seqId)" << endl; f_types_ << indent() << " x.Write(oprot)" << endl; f_types_ << indent() << " oprot.WriteMessageEnd()" << endl; - f_types_ << indent() << " oprot.Flush()" << endl; + f_types_ << indent() << " oprot.Flush(ctx)" << endl; } f_types_ << indent() << " return true, err2" << endl; @@ -2746,7 +2733,7 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function* << endl; f_types_ << indent() << " err = err2" << endl; f_types_ << indent() << "}" << endl; - f_types_ << indent() << "if err2 = oprot.Flush(); err == nil && err2 != nil {" << endl; + f_types_ << indent() << "if err2 = oprot.Flush(ctx); err == nil && err2 != nil {" << endl; f_types_ << indent() << " err = err2" << endl; f_types_ << indent() << "}" << endl; f_types_ << indent() << "if err != nil {" << endl; @@ -3642,6 +3629,4 @@ THRIFT_REGISTER_GENERATOR(go, "Go", " ignore_initialisms\n" " Disable automatic spelling correction of initialisms (e.g. \"URL\")\n" \ " read_write_private\n" - " Make read/write methods private, default is public Read/Write\n" \ - " legacy_context\n" - " Use legacy x/net/context instead of context in go<1.7.\n") + " Make read/write methods private, default is public Read/Write\n") diff --git a/compiler/cpp/src/thrift/generate/thrift-t_php_generator.o-a60a38e9 b/compiler/cpp/src/thrift/generate/thrift-t_php_generator.o-a60a38e9 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/go/Makefile.am b/lib/go/Makefile.am index 0d597101447..0dfa5fadca7 100644 --- a/lib/go/Makefile.am +++ b/lib/go/Makefile.am @@ -31,14 +31,12 @@ install: @echo '##############################################################' check-local: - GOPATH=`pwd` $(GO) get golang.org/x/net/context GOPATH=`pwd` $(GO) test -race ./thrift clean-local: $(RM) -rf pkg all-local: - GOPATH=`pwd` $(GO) get golang.org/x/net/context GOPATH=`pwd` $(GO) build ./thrift EXTRA_DIST = \ diff --git a/lib/go/README.md b/lib/go/README.md index 7440474c325..debc9ac680e 100644 --- a/lib/go/README.md +++ b/lib/go/README.md @@ -24,6 +24,8 @@ under the License. Using Thrift with Go ==================== +Thrift supports Go 1.7+ + In following Go conventions, we recommend you use the 'go' tool to install Thrift for go. diff --git a/lib/go/test/Makefile.am b/lib/go/test/Makefile.am index 842f2de6180..e93ec5caf5a 100644 --- a/lib/go/test/Makefile.am +++ b/lib/go/test/Makefile.am @@ -17,10 +17,6 @@ # under the License. # -if GOVERSION_LT_17 -COMPILER_EXTRAFLAG=",legacy_context" -endif - THRIFTARGS = -out gopath/src/ --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG) THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift @@ -59,7 +55,6 @@ gopath: $(THRIFT) $(THRIFTTEST) \ $(THRIFT) $(THRIFTARGS) InitialismsTest.thrift $(THRIFT) $(THRIFTARGS),read_write_private DontExportRWTest.thrift $(THRIFT) $(THRIFTARGS),ignore_initialisms IgnoreInitialismsTest.thrift - GOPATH=`pwd`/gopath $(GO) get golang.org/x/net/context GOPATH=`pwd`/gopath $(GO) get github.com/golang/mock/gomock || true sed -i 's/\"context\"/\"golang.org\/x\/net\/context\"/g' gopath/src/github.com/golang/mock/gomock/controller.go || true GOPATH=`pwd`/gopath $(GO) get github.com/golang/mock/gomock diff --git a/lib/go/test/tests/client_error_test.go b/lib/go/test/tests/client_error_test.go index 5dec472eba7..fdec4ea57f2 100644 --- a/lib/go/test/tests/client_error_test.go +++ b/lib/go/test/tests/client_error_test.go @@ -20,6 +20,7 @@ package tests import ( + "context" "errors" "errortest" "testing" @@ -212,7 +213,7 @@ func prepareClientCallReply(protocol *MockTProtocol, failAt int, failWith error) if failAt == 25 { err = failWith } - last = protocol.EXPECT().Flush().Return(err).After(last) + last = protocol.EXPECT().Flush(context.Background()).Return(err).After(last) if failAt == 25 { return true } @@ -536,7 +537,7 @@ func prepareClientCallException(protocol *MockTProtocol, failAt int, failWith er last = protocol.EXPECT().WriteFieldStop().After(last) last = protocol.EXPECT().WriteStructEnd().After(last) last = protocol.EXPECT().WriteMessageEnd().After(last) - last = protocol.EXPECT().Flush().After(last) + last = protocol.EXPECT().Flush(context.Background()).After(last) // Reading the exception, might fail. if failAt == 0 { @@ -704,7 +705,7 @@ func TestClientSeqIdMismatch(t *testing.T) { protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteMessageEnd(), - protocol.EXPECT().Flush(), + protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil), ) @@ -735,7 +736,7 @@ func TestClientSeqIdMismatchLegeacy(t *testing.T) { protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteMessageEnd(), - protocol.EXPECT().Flush(), + protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil), ) @@ -764,7 +765,7 @@ func TestClientWrongMethodName(t *testing.T) { protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteMessageEnd(), - protocol.EXPECT().Flush(), + protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil), ) @@ -795,7 +796,7 @@ func TestClientWrongMethodNameLegacy(t *testing.T) { protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteMessageEnd(), - protocol.EXPECT().Flush(), + protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil), ) @@ -824,7 +825,7 @@ func TestClientWrongMessageType(t *testing.T) { protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteMessageEnd(), - protocol.EXPECT().Flush(), + protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil), ) @@ -855,7 +856,7 @@ func TestClientWrongMessageTypeLegacy(t *testing.T) { protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteMessageEnd(), - protocol.EXPECT().Flush(), + protocol.EXPECT().Flush(context.Background()), protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil), ) diff --git a/tutorial/go/src/go17.go b/lib/go/test/tests/context.go similarity index 94% rename from tutorial/go/src/go17.go rename to lib/go/test/tests/context.go index a6003a9174f..a93a82b8fc9 100644 --- a/tutorial/go/src/go17.go +++ b/lib/go/test/tests/context.go @@ -1,5 +1,3 @@ -// +build go1.7 - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -19,8 +17,10 @@ * under the License. */ -package main +package tests -import "context" +import ( + "context" +) var defaultCtx = context.Background() diff --git a/lib/go/test/tests/go17.go b/lib/go/test/tests/go17.go deleted file mode 100644 index dc3c9d598e1..00000000000 --- a/lib/go/test/tests/go17.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 tests - -import ( - "context" - "fmt" -) - -var defaultCtx = context.Background() - -type FirstImpl struct{} - -func (f *FirstImpl) ReturnOne(ctx context.Context) (r int64, err error) { - return 1, nil -} - -type SecondImpl struct{} - -func (s *SecondImpl) ReturnTwo(ctx context.Context) (r int64, err error) { - return 2, nil -} - -type impl struct{} - -func (i *impl) Hi(ctx context.Context, in int64, s string) (err error) { fmt.Println("Hi!"); return } -func (i *impl) Emptyfunc(ctx context.Context) (err error) { return } -func (i *impl) EchoInt(ctx context.Context, param int64) (r int64, err error) { return param, nil } diff --git a/lib/go/test/tests/multiplexed_protocol_test.go b/lib/go/test/tests/multiplexed_protocol_test.go index 0b5896b6065..61ac62828d4 100644 --- a/lib/go/test/tests/multiplexed_protocol_test.go +++ b/lib/go/test/tests/multiplexed_protocol_test.go @@ -20,6 +20,7 @@ package tests import ( + "context" "multiplexedprotocoltest" "net" "testing" @@ -36,6 +37,18 @@ func FindAvailableTCPServerPort() net.Addr { } } +type FirstImpl struct{} + +func (f *FirstImpl) ReturnOne(ctx context.Context) (r int64, err error) { + return 1, nil +} + +type SecondImpl struct{} + +func (s *SecondImpl) ReturnTwo(ctx context.Context) (r int64, err error) { + return 2, nil +} + func createTransport(addr net.Addr) (thrift.TTransport, error) { socket := thrift.NewTSocketFromAddrTimeout(addr, TIMEOUT) transport := thrift.NewTFramedTransport(socket) diff --git a/lib/go/test/tests/one_way_test.go b/lib/go/test/tests/one_way_test.go index 8abd671e617..48d0bbe3890 100644 --- a/lib/go/test/tests/one_way_test.go +++ b/lib/go/test/tests/one_way_test.go @@ -20,6 +20,8 @@ package tests import ( + "context" + "fmt" "net" "onewaytest" "testing" @@ -36,6 +38,12 @@ func findPort() net.Addr { } } +type impl struct{} + +func (i *impl) Hi(ctx context.Context, in int64, s string) (err error) { fmt.Println("Hi!"); return } +func (i *impl) Emptyfunc(ctx context.Context) (err error) { return } +func (i *impl) EchoInt(ctx context.Context, param int64) (r int64, err error) { return param, nil } + const TIMEOUT = time.Second var addr net.Addr diff --git a/lib/go/test/tests/pre_go17.go b/lib/go/test/tests/pre_go17.go deleted file mode 100644 index 8ab433121f2..00000000000 --- a/lib/go/test/tests/pre_go17.go +++ /dev/null @@ -1,48 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 tests - -import ( - "fmt" - - "golang.org/x/net/context" -) - -var defaultCtx = context.Background() - -type FirstImpl struct{} - -func (f *FirstImpl) ReturnOne(ctx context.Context) (r int64, err error) { - return 1, nil -} - -type SecondImpl struct{} - -func (s *SecondImpl) ReturnTwo(ctx context.Context) (r int64, err error) { - return 2, nil -} - -type impl struct{} - -func (i *impl) Hi(ctx context.Context, in int64, s string) (err error) { fmt.Println("Hi!"); return } -func (i *impl) Emptyfunc(ctx context.Context) (err error) { return } -func (i *impl) EchoInt(ctx context.Context, param int64) (r int64, err error) { return param, nil } diff --git a/lib/go/test/tests/protocol_mock.go b/lib/go/test/tests/protocol_mock.go index 8476c8661a6..51d7a02ff7b 100644 --- a/lib/go/test/tests/protocol_mock.go +++ b/lib/go/test/tests/protocol_mock.go @@ -23,6 +23,7 @@ package tests import ( + "context" thrift "thrift" gomock "github.com/golang/mock/gomock" @@ -49,13 +50,13 @@ func (_m *MockTProtocol) EXPECT() *_MockTProtocolRecorder { return _m.recorder } -func (_m *MockTProtocol) Flush() error { +func (_m *MockTProtocol) Flush(ctx context.Context) error { ret := _m.ctrl.Call(_m, "Flush") ret0, _ := ret[0].(error) return ret0 } -func (_mr *_MockTProtocolRecorder) Flush() *gomock.Call { +func (_mr *_MockTProtocolRecorder) Flush(ctx context.Context) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Flush") } diff --git a/lib/go/test/tests/thrifttest_handler.go b/lib/go/test/tests/thrifttest_handler.go index 6542fac584d..31b9ee23eca 100644 --- a/lib/go/test/tests/thrifttest_handler.go +++ b/lib/go/test/tests/thrifttest_handler.go @@ -1,5 +1,3 @@ -// +build !go1.7 - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -22,12 +20,11 @@ package tests import ( + "context" "errors" "thrift" "thrifttest" "time" - - "golang.org/x/net/context" ) type SecondServiceHandler struct { diff --git a/lib/go/test/tests/thrifttest_handler_go17.go b/lib/go/test/tests/thrifttest_handler_go17.go deleted file mode 100644 index e022a3df1fb..00000000000 --- a/lib/go/test/tests/thrifttest_handler_go17.go +++ /dev/null @@ -1,212 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 tests - -import ( - "context" - "errors" - "thrift" - "thrifttest" - "time" -) - -type SecondServiceHandler struct { -} - -func NewSecondServiceHandler() *SecondServiceHandler { - return &SecondServiceHandler{} -} - -func (p *SecondServiceHandler) BlahBlah(ctx context.Context) (err error) { - return nil -} - -func (p *SecondServiceHandler) SecondtestString(ctx context.Context, thing string) (r string, err error) { - return thing, nil -} - -type ThriftTestHandler struct { -} - -func NewThriftTestHandler() *ThriftTestHandler { - return &ThriftTestHandler{} -} - -func (p *ThriftTestHandler) TestVoid(ctx context.Context) (err error) { - return nil -} - -func (p *ThriftTestHandler) TestString(ctx context.Context, thing string) (r string, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestBool(ctx context.Context, thing bool) (r bool, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestByte(ctx context.Context, thing int8) (r int8, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestI32(ctx context.Context, thing int32) (r int32, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestI64(ctx context.Context, thing int64) (r int64, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestDouble(ctx context.Context, thing float64) (r float64, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestBinary(ctx context.Context, thing []byte) (r []byte, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestStruct(ctx context.Context, thing *thrifttest.Xtruct) (r *thrifttest.Xtruct, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestNest(ctx context.Context, thing *thrifttest.Xtruct2) (r *thrifttest.Xtruct2, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestMap(ctx context.Context, thing map[int32]int32) (r map[int32]int32, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestStringMap(ctx context.Context, thing map[string]string) (r map[string]string, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestSet(ctx context.Context, thing []int32) (r []int32, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestList(ctx context.Context, thing []int32) (r []int32, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestEnum(ctx context.Context, thing thrifttest.Numberz) (r thrifttest.Numberz, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestTypedef(ctx context.Context, thing thrifttest.UserId) (r thrifttest.UserId, err error) { - return thing, nil -} - -func (p *ThriftTestHandler) TestMapMap(ctx context.Context, hello int32) (r map[int32]map[int32]int32, err error) { - r = make(map[int32]map[int32]int32) - pos := make(map[int32]int32) - neg := make(map[int32]int32) - - for i := int32(1); i < 5; i++ { - pos[i] = i - neg[-i] = -i - } - r[4] = pos - r[-4] = neg - - return r, nil -} - -func (p *ThriftTestHandler) TestInsanity(ctx context.Context, argument *thrifttest.Insanity) (r map[thrifttest.UserId]map[thrifttest.Numberz]*thrifttest.Insanity, err error) { - hello := thrifttest.NewXtruct() - hello.StringThing = "Hello2" - hello.ByteThing = 2 - hello.I32Thing = 2 - hello.I64Thing = 2 - - goodbye := thrifttest.NewXtruct() - goodbye.StringThing = "Goodbye4" - goodbye.ByteThing = 4 - goodbye.I32Thing = 4 - goodbye.I64Thing = 4 - - crazy := thrifttest.NewInsanity() - crazy.UserMap = make(map[thrifttest.Numberz]thrifttest.UserId) - crazy.UserMap[thrifttest.Numberz_EIGHT] = 8 - crazy.UserMap[thrifttest.Numberz_FIVE] = 5 - crazy.Xtructs = []*thrifttest.Xtruct{goodbye, hello} - - first_map := make(map[thrifttest.Numberz]*thrifttest.Insanity) - second_map := make(map[thrifttest.Numberz]*thrifttest.Insanity) - - first_map[thrifttest.Numberz_TWO] = crazy - first_map[thrifttest.Numberz_THREE] = crazy - - looney := thrifttest.NewInsanity() - second_map[thrifttest.Numberz_SIX] = looney - - var insane = make(map[thrifttest.UserId]map[thrifttest.Numberz]*thrifttest.Insanity) - insane[1] = first_map - insane[2] = second_map - - return insane, nil -} - -func (p *ThriftTestHandler) TestMulti(ctx context.Context, arg0 int8, arg1 int32, arg2 int64, arg3 map[int16]string, arg4 thrifttest.Numberz, arg5 thrifttest.UserId) (r *thrifttest.Xtruct, err error) { - r = thrifttest.NewXtruct() - r.StringThing = "Hello2" - r.ByteThing = arg0 - r.I32Thing = arg1 - r.I64Thing = arg2 - return r, nil -} - -func (p *ThriftTestHandler) TestException(ctx context.Context, arg string) (err error) { - if arg == "Xception" { - x := thrifttest.NewXception() - x.ErrorCode = 1001 - x.Message = arg - return x - } else if arg == "TException" { - return thrift.TException(errors.New(arg)) - } else { - return nil - } -} - -func (p *ThriftTestHandler) TestMultiException(ctx context.Context, arg0 string, arg1 string) (r *thrifttest.Xtruct, err error) { - if arg0 == "Xception" { - x := thrifttest.NewXception() - x.ErrorCode = 1001 - x.Message = "This is an Xception" - return nil, x - } else if arg0 == "Xception2" { - x2 := thrifttest.NewXception2() - x2.ErrorCode = 2002 - x2.StructThing = thrifttest.NewXtruct() - x2.StructThing.StringThing = "This is an Xception2" - return nil, x2 - } - - res := thrifttest.NewXtruct() - res.StringThing = arg1 - return res, nil -} - -func (p *ThriftTestHandler) TestOneway(ctx context.Context, secondsToSleep int32) (err error) { - time.Sleep(time.Second * time.Duration(secondsToSleep)) - return nil -} diff --git a/lib/go/thrift/binary_protocol.go b/lib/go/thrift/binary_protocol.go index 690d341111b..de0f6a7a5cb 100644 --- a/lib/go/thrift/binary_protocol.go +++ b/lib/go/thrift/binary_protocol.go @@ -21,6 +21,7 @@ package thrift import ( "bytes" + "context" "encoding/binary" "errors" "fmt" @@ -457,8 +458,8 @@ func (p *TBinaryProtocol) ReadBinary() ([]byte, error) { return buf, NewTProtocolException(err) } -func (p *TBinaryProtocol) Flush() (err error) { - return NewTProtocolException(p.trans.Flush()) +func (p *TBinaryProtocol) Flush(ctx context.Context) (err error) { + return NewTProtocolException(p.trans.Flush(ctx)) } func (p *TBinaryProtocol) Skip(fieldType TType) (err error) { diff --git a/lib/go/thrift/buffered_transport.go b/lib/go/thrift/buffered_transport.go index b754f925d08..96702061b2f 100644 --- a/lib/go/thrift/buffered_transport.go +++ b/lib/go/thrift/buffered_transport.go @@ -21,6 +21,7 @@ package thrift import ( "bufio" + "context" ) type TBufferedTransportFactory struct { @@ -78,12 +79,12 @@ func (p *TBufferedTransport) Write(b []byte) (int, error) { return n, err } -func (p *TBufferedTransport) Flush() error { +func (p *TBufferedTransport) Flush(ctx context.Context) error { if err := p.ReadWriter.Flush(); err != nil { p.ReadWriter.Writer.Reset(p.tp) return err } - return p.tp.Flush() + return p.tp.Flush(ctx) } func (p *TBufferedTransport) RemainingBytes() (num_bytes uint64) { diff --git a/lib/go/thrift/client.go b/lib/go/thrift/client.go index 8bdb53d8d9f..28791ccd0c0 100644 --- a/lib/go/thrift/client.go +++ b/lib/go/thrift/client.go @@ -1,6 +1,13 @@ package thrift -import "fmt" +import ( + "context" + "fmt" +) + +type TClient interface { + Call(ctx context.Context, method string, args, result TStruct) error +} type TStandardClient struct { seqId int32 @@ -16,7 +23,7 @@ func NewTStandardClient(inputProtocol, outputProtocol TProtocol) *TStandardClien } } -func (p *TStandardClient) Send(oprot TProtocol, seqId int32, method string, args TStruct) error { +func (p *TStandardClient) Send(ctx context.Context, oprot TProtocol, seqId int32, method string, args TStruct) error { if err := oprot.WriteMessageBegin(method, CALL, seqId); err != nil { return err } @@ -26,7 +33,7 @@ func (p *TStandardClient) Send(oprot TProtocol, seqId int32, method string, args if err := oprot.WriteMessageEnd(); err != nil { return err } - return oprot.Flush() + return oprot.Flush(ctx) } func (p *TStandardClient) Recv(iprot TProtocol, seqId int32, method string, result TStruct) error { @@ -61,11 +68,11 @@ func (p *TStandardClient) Recv(iprot TProtocol, seqId int32, method string, resu return iprot.ReadMessageEnd() } -func (p *TStandardClient) call(method string, args, result TStruct) error { +func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) error { p.seqId++ seqId := p.seqId - if err := p.Send(p.oprot, seqId, method, args); err != nil { + if err := p.Send(ctx, p.oprot, seqId, method, args); err != nil { return err } diff --git a/lib/go/thrift/client_go17.go b/lib/go/thrift/client_go17.go deleted file mode 100644 index 15c1c52ca69..00000000000 --- a/lib/go/thrift/client_go17.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build go1.7 - -package thrift - -import "context" - -type TClient interface { - Call(ctx context.Context, method string, args, result TStruct) error -} - -func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) error { - return p.call(method, args, result) -} diff --git a/lib/go/thrift/client_pre_go17.go b/lib/go/thrift/client_pre_go17.go deleted file mode 100644 index d2e99ef2af9..00000000000 --- a/lib/go/thrift/client_pre_go17.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !go1.7 - -package thrift - -import "golang.org/x/net/context" - -type TClient interface { - Call(ctx context.Context, method string, args, result TStruct) error -} - -func (p *TStandardClient) Call(ctx context.Context, method string, args, result TStruct) error { - return p.call(method, args, result) -} diff --git a/lib/go/thrift/common_test_go17.go b/lib/go/thrift/common_test.go similarity index 98% rename from lib/go/thrift/common_test_go17.go rename to lib/go/thrift/common_test.go index 2c729a2269e..93597ff8a2a 100644 --- a/lib/go/thrift/common_test_go17.go +++ b/lib/go/thrift/common_test.go @@ -1,5 +1,3 @@ -// +build go1.7 - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/lib/go/thrift/common_test_pre_go17.go b/lib/go/thrift/common_test_pre_go17.go deleted file mode 100644 index e6d0c4d9afb..00000000000 --- a/lib/go/thrift/common_test_pre_go17.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import "golang.org/x/net/context" - -type mockProcessor struct { - ProcessFunc func(in, out TProtocol) (bool, TException) -} - -func (m *mockProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { - return m.ProcessFunc(in, out) -} diff --git a/lib/go/thrift/compact_protocol.go b/lib/go/thrift/compact_protocol.go index 0bc5fddeb38..fc1d18287ed 100644 --- a/lib/go/thrift/compact_protocol.go +++ b/lib/go/thrift/compact_protocol.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "encoding/binary" "fmt" "io" @@ -599,8 +600,8 @@ func (p *TCompactProtocol) ReadBinary() (value []byte, err error) { return buf, NewTProtocolException(e) } -func (p *TCompactProtocol) Flush() (err error) { - return NewTProtocolException(p.trans.Flush()) +func (p *TCompactProtocol) Flush(ctx context.Context) (err error) { + return NewTProtocolException(p.trans.Flush(ctx)) } func (p *TCompactProtocol) Skip(fieldType TType) (err error) { diff --git a/lib/go/thrift/go17.go b/lib/go/thrift/context.go similarity index 98% rename from lib/go/thrift/go17.go rename to lib/go/thrift/context.go index e3b21c4b731..d15c1bcf894 100644 --- a/lib/go/thrift/go17.go +++ b/lib/go/thrift/context.go @@ -1,5 +1,3 @@ -// +build go1.7 - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/lib/go/thrift/debug_protocol.go b/lib/go/thrift/debug_protocol.go index d37252cc61d..57943e0f35d 100644 --- a/lib/go/thrift/debug_protocol.go +++ b/lib/go/thrift/debug_protocol.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "log" ) @@ -258,8 +259,8 @@ func (tdp *TDebugProtocol) Skip(fieldType TType) (err error) { log.Printf("%sSkip(fieldType=%#v) (err=%#v)", tdp.LogPrefix, fieldType, err) return } -func (tdp *TDebugProtocol) Flush() (err error) { - err = tdp.Delegate.Flush() +func (tdp *TDebugProtocol) Flush(ctx context.Context) (err error) { + err = tdp.Delegate.Flush(ctx) log.Printf("%sFlush() (err=%#v)", tdp.LogPrefix, err) return } diff --git a/lib/go/thrift/framed_transport.go b/lib/go/thrift/framed_transport.go index 60b1249915a..81fa65aaae5 100644 --- a/lib/go/thrift/framed_transport.go +++ b/lib/go/thrift/framed_transport.go @@ -22,6 +22,7 @@ package thrift import ( "bufio" "bytes" + "context" "encoding/binary" "fmt" "io" @@ -135,7 +136,7 @@ func (p *TFramedTransport) WriteString(s string) (n int, err error) { return p.buf.WriteString(s) } -func (p *TFramedTransport) Flush() error { +func (p *TFramedTransport) Flush(ctx context.Context) error { size := p.buf.Len() buf := p.buffer[:4] binary.BigEndian.PutUint32(buf, uint32(size)) @@ -151,7 +152,7 @@ func (p *TFramedTransport) Flush() error { return NewTTransportExceptionFromError(err) } } - err = p.transport.Flush() + err = p.transport.Flush(ctx) return NewTTransportExceptionFromError(err) } diff --git a/lib/go/thrift/http_client.go b/lib/go/thrift/http_client.go index 33f2aa4b594..5c82bf53875 100644 --- a/lib/go/thrift/http_client.go +++ b/lib/go/thrift/http_client.go @@ -21,6 +21,7 @@ package thrift import ( "bytes" + "context" "io" "io/ioutil" "net/http" @@ -181,7 +182,7 @@ func (p *THttpClient) WriteString(s string) (n int, err error) { return p.requestBuffer.WriteString(s) } -func (p *THttpClient) Flush() error { +func (p *THttpClient) Flush(ctx context.Context) error { // Close any previous response body to avoid leaking connections. p.closeResponse() @@ -190,6 +191,9 @@ func (p *THttpClient) Flush() error { return NewTTransportExceptionFromError(err) } req.Header = p.header + if ctx != nil { + req = req.WithContext(ctx) + } response, err := p.client.Do(req) if err != nil { return NewTTransportExceptionFromError(err) diff --git a/lib/go/thrift/http_transport.go b/lib/go/thrift/http_transport.go index 601855b926c..66f0f388a09 100644 --- a/lib/go/thrift/http_transport.go +++ b/lib/go/thrift/http_transport.go @@ -26,6 +26,18 @@ import ( "strings" ) +// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function +func NewThriftHandlerFunc(processor TProcessor, + inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { + + return gz(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/x-thrift") + + transport := NewStreamTransport(r.Body, w) + processor.Process(r.Context(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) + }) +} + // gz transparently compresses the HTTP response if the client supports it. func gz(handler http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { diff --git a/lib/go/thrift/http_transport_go17.go b/lib/go/thrift/http_transport_go17.go deleted file mode 100644 index 1313ac225ba..00000000000 --- a/lib/go/thrift/http_transport_go17.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import ( - "net/http" -) - -// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function -func NewThriftHandlerFunc(processor TProcessor, - inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { - - return gz(func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/x-thrift") - - transport := NewStreamTransport(r.Body, w) - processor.Process(r.Context(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) - }) -} diff --git a/lib/go/thrift/http_transport_pre_go17.go b/lib/go/thrift/http_transport_pre_go17.go deleted file mode 100644 index 13aa1c11d1a..00000000000 --- a/lib/go/thrift/http_transport_pre_go17.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import ( - "net/http" - - "golang.org/x/net/context" -) - -// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function -func NewThriftHandlerFunc(processor TProcessor, - inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { - - return gz(func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", "application/x-thrift") - - transport := NewStreamTransport(r.Body, w) - processor.Process(context.Background(), inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) - }) -} diff --git a/lib/go/thrift/iostream_transport.go b/lib/go/thrift/iostream_transport.go index b18be81c46f..fea93bceffa 100644 --- a/lib/go/thrift/iostream_transport.go +++ b/lib/go/thrift/iostream_transport.go @@ -21,6 +21,7 @@ package thrift import ( "bufio" + "context" "io" ) @@ -138,7 +139,7 @@ func (p *StreamTransport) Close() error { } // Flushes the underlying output stream if not null. -func (p *StreamTransport) Flush() error { +func (p *StreamTransport) Flush(ctx context.Context) error { if p.Writer == nil { return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream") } diff --git a/lib/go/thrift/json_protocol.go b/lib/go/thrift/json_protocol.go index 442fa9144d4..7be685d43f2 100644 --- a/lib/go/thrift/json_protocol.go +++ b/lib/go/thrift/json_protocol.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "encoding/base64" "fmt" ) @@ -438,10 +439,10 @@ func (p *TJSONProtocol) ReadBinary() ([]byte, error) { return v, p.ParsePostValue() } -func (p *TJSONProtocol) Flush() (err error) { +func (p *TJSONProtocol) Flush(ctx context.Context) (err error) { err = p.writer.Flush() if err == nil { - err = p.trans.Flush() + err = p.trans.Flush(ctx) } return NewTProtocolException(err) } diff --git a/lib/go/thrift/json_protocol_test.go b/lib/go/thrift/json_protocol_test.go index 7104ce3a02e..0902f1b21f8 100644 --- a/lib/go/thrift/json_protocol_test.go +++ b/lib/go/thrift/json_protocol_test.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "encoding/base64" "encoding/json" "fmt" @@ -36,7 +37,7 @@ func TestWriteJSONProtocolBool(t *testing.T) { if e := p.WriteBool(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -68,7 +69,7 @@ func TestReadJSONProtocolBool(t *testing.T) { } else { trans.Write([]byte{'0'}) // not JSON_FALSE } - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBool() if e != nil { @@ -94,7 +95,7 @@ func TestWriteJSONProtocolByte(t *testing.T) { if e := p.WriteByte(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -116,7 +117,7 @@ func TestReadJSONProtocolByte(t *testing.T) { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadByte() if e != nil { @@ -141,7 +142,7 @@ func TestWriteJSONProtocolI16(t *testing.T) { if e := p.WriteI16(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -163,7 +164,7 @@ func TestReadJSONProtocolI16(t *testing.T) { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI16() if e != nil { @@ -188,7 +189,7 @@ func TestWriteJSONProtocolI32(t *testing.T) { if e := p.WriteI32(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -210,7 +211,7 @@ func TestReadJSONProtocolI32(t *testing.T) { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI32() if e != nil { @@ -235,7 +236,7 @@ func TestWriteJSONProtocolI64(t *testing.T) { if e := p.WriteI64(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -257,7 +258,7 @@ func TestReadJSONProtocolI64(t *testing.T) { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(strconv.FormatInt(value, 10)) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI64() if e != nil { @@ -282,7 +283,7 @@ func TestWriteJSONProtocolDouble(t *testing.T) { if e := p.WriteDouble(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -319,7 +320,7 @@ func TestReadJSONProtocolDouble(t *testing.T) { p := NewTJSONProtocol(trans) n := NewNumericFromDouble(value) trans.WriteString(n.String()) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadDouble() if e != nil { @@ -358,7 +359,7 @@ func TestWriteJSONProtocolString(t *testing.T) { if e := p.WriteString(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -380,7 +381,7 @@ func TestReadJSONProtocolString(t *testing.T) { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(jsonQuote(value)) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadString() if e != nil { @@ -409,7 +410,7 @@ func TestWriteJSONProtocolBinary(t *testing.T) { if e := p.WriteBinary(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -441,7 +442,7 @@ func TestReadJSONProtocolBinary(t *testing.T) { trans := NewTMemoryBuffer() p := NewTJSONProtocol(trans) trans.WriteString(jsonQuote(b64String)) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBinary() if e != nil { @@ -474,7 +475,7 @@ func TestWriteJSONProtocolList(t *testing.T) { } } p.WriteListEnd() - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() @@ -528,7 +529,7 @@ func TestWriteJSONProtocolSet(t *testing.T) { } } p.WriteSetEnd() - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() @@ -585,7 +586,7 @@ func TestWriteJSONProtocolMap(t *testing.T) { } } p.WriteMapEnd() - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() diff --git a/lib/go/thrift/memory_buffer.go b/lib/go/thrift/memory_buffer.go index 97a4edfa5db..5936d273037 100644 --- a/lib/go/thrift/memory_buffer.go +++ b/lib/go/thrift/memory_buffer.go @@ -21,6 +21,7 @@ package thrift import ( "bytes" + "context" ) // Memory buffer-based implementation of the TTransport interface. @@ -70,7 +71,7 @@ func (p *TMemoryBuffer) Close() error { } // Flushing a memory buffer is a no-op -func (p *TMemoryBuffer) Flush() error { +func (p *TMemoryBuffer) Flush(ctx context.Context) error { return nil } diff --git a/lib/go/thrift/multiplexed_protocol.go b/lib/go/thrift/multiplexed_protocol.go index b7f4f8a1ccc..d028a30b333 100644 --- a/lib/go/thrift/multiplexed_protocol.go +++ b/lib/go/thrift/multiplexed_protocol.go @@ -19,6 +19,12 @@ package thrift +import ( + "context" + "fmt" + "strings" +) + /* TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift client to communicate with a multiplexing Thrift server, @@ -122,6 +128,31 @@ func (t *TMultiplexedProcessor) RegisterProcessor(name string, processor TProces t.serviceProcessorMap[name] = processor } +func (t *TMultiplexedProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { + name, typeId, seqid, err := in.ReadMessageBegin() + if err != nil { + return false, err + } + if typeId != CALL && typeId != ONEWAY { + return false, fmt.Errorf("Unexpected message type %v", typeId) + } + //extract the service name + v := strings.SplitN(name, MULTIPLEXED_SEPARATOR, 2) + if len(v) != 2 { + if t.DefaultProcessor != nil { + smb := NewStoredMessageProtocol(in, name, typeId, seqid) + return t.DefaultProcessor.Process(ctx, smb, out) + } + return false, fmt.Errorf("Service name not found in message name: %s. Did you forget to use a TMultiplexProtocol in your client?", name) + } + actualProcessor, ok := t.serviceProcessorMap[v[0]] + if !ok { + return false, fmt.Errorf("Service name not found: %s. Did you forget to call registerProcessor()?", v[0]) + } + smb := NewStoredMessageProtocol(in, v[1], typeId, seqid) + return actualProcessor.Process(ctx, smb, out) +} + //Protocol that use stored message for ReadMessageBegin type storedMessageProtocol struct { TProtocol diff --git a/lib/go/thrift/multiplexed_protocol_go17.go b/lib/go/thrift/multiplexed_protocol_go17.go deleted file mode 100644 index c71035e680c..00000000000 --- a/lib/go/thrift/multiplexed_protocol_go17.go +++ /dev/null @@ -1,53 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import ( - "context" - "fmt" - "strings" -) - -func (t *TMultiplexedProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { - name, typeId, seqid, err := in.ReadMessageBegin() - if err != nil { - return false, err - } - if typeId != CALL && typeId != ONEWAY { - return false, fmt.Errorf("Unexpected message type %v", typeId) - } - //extract the service name - v := strings.SplitN(name, MULTIPLEXED_SEPARATOR, 2) - if len(v) != 2 { - if t.DefaultProcessor != nil { - smb := NewStoredMessageProtocol(in, name, typeId, seqid) - return t.DefaultProcessor.Process(ctx, smb, out) - } - return false, fmt.Errorf("Service name not found in message name: %s. Did you forget to use a TMultiplexProtocol in your client?", name) - } - actualProcessor, ok := t.serviceProcessorMap[v[0]] - if !ok { - return false, fmt.Errorf("Service name not found: %s. Did you forget to call registerProcessor()?", v[0]) - } - smb := NewStoredMessageProtocol(in, v[1], typeId, seqid) - return actualProcessor.Process(ctx, smb, out) -} diff --git a/lib/go/thrift/multiplexed_protocol_pre_go17.go b/lib/go/thrift/multiplexed_protocol_pre_go17.go deleted file mode 100644 index 5c27b38755c..00000000000 --- a/lib/go/thrift/multiplexed_protocol_pre_go17.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import ( - "fmt" - "strings" - - "golang.org/x/net/context" -) - -func (t *TMultiplexedProcessor) Process(ctx context.Context, in, out TProtocol) (bool, TException) { - name, typeId, seqid, err := in.ReadMessageBegin() - if err != nil { - return false, err - } - if typeId != CALL && typeId != ONEWAY { - return false, fmt.Errorf("Unexpected message type %v", typeId) - } - //extract the service name - v := strings.SplitN(name, MULTIPLEXED_SEPARATOR, 2) - if len(v) != 2 { - if t.DefaultProcessor != nil { - smb := NewStoredMessageProtocol(in, name, typeId, seqid) - return t.DefaultProcessor.Process(ctx, smb, out) - } - return false, fmt.Errorf("Service name not found in message name: %s. Did you forget to use a TMultiplexProtocol in your client?", name) - } - actualProcessor, ok := t.serviceProcessorMap[v[0]] - if !ok { - return false, fmt.Errorf("Service name not found: %s. Did you forget to call registerProcessor()?", v[0]) - } - smb := NewStoredMessageProtocol(in, v[1], typeId, seqid) - return actualProcessor.Process(ctx, smb, out) -} diff --git a/lib/go/thrift/pre_go17.go b/lib/go/thrift/pre_go17.go deleted file mode 100644 index cb564b8dbd6..00000000000 --- a/lib/go/thrift/pre_go17.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import "golang.org/x/net/context" - -var defaultCtx = context.Background() diff --git a/lib/go/thrift/processor.go b/lib/go/thrift/processor.go deleted file mode 100644 index 566aaaf7182..00000000000 --- a/lib/go/thrift/processor.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import "golang.org/x/net/context" - -// A processor is a generic object which operates upon an input stream and -// writes to some output stream. -type TProcessor interface { - Process(ctx context.Context, in, out TProtocol) (bool, TException) -} - -type TProcessorFunction interface { - Process(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) -} diff --git a/lib/go/thrift/processor_factory.go b/lib/go/thrift/processor_factory.go index 9d645df2446..e4b132b307c 100644 --- a/lib/go/thrift/processor_factory.go +++ b/lib/go/thrift/processor_factory.go @@ -19,6 +19,18 @@ package thrift +import "context" + +// A processor is a generic object which operates upon an input stream and +// writes to some output stream. +type TProcessor interface { + Process(ctx context.Context, in, out TProtocol) (bool, TException) +} + +type TProcessorFunction interface { + Process(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) +} + // The default processor factory just returns a singleton // instance. type TProcessorFactory interface { diff --git a/lib/go/thrift/processor_go17.go b/lib/go/thrift/processor_go17.go deleted file mode 100644 index fb0b165dcc7..00000000000 --- a/lib/go/thrift/processor_go17.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 thrift - -import "context" - -// A processor is a generic object which operates upon an input stream and -// writes to some output stream. -type TProcessor interface { - Process(ctx context.Context, in, out TProtocol) (bool, TException) -} - -type TProcessorFunction interface { - Process(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException) -} diff --git a/lib/go/thrift/protocol.go b/lib/go/thrift/protocol.go index 25e6d24b904..615b7a4a8f3 100644 --- a/lib/go/thrift/protocol.go +++ b/lib/go/thrift/protocol.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "errors" "fmt" ) @@ -74,7 +75,7 @@ type TProtocol interface { ReadBinary() (value []byte, err error) Skip(fieldType TType) (err error) - Flush() (err error) + Flush(ctx context.Context) (err error) Transport() TTransport } diff --git a/lib/go/thrift/protocol_test.go b/lib/go/thrift/protocol_test.go index 2573312d1d3..2e3b65df99b 100644 --- a/lib/go/thrift/protocol_test.go +++ b/lib/go/thrift/protocol_test.go @@ -21,6 +21,7 @@ package thrift import ( "bytes" + "context" "io/ioutil" "math" "net" @@ -234,7 +235,7 @@ func ReadWriteBool(t testing.TB, p TProtocol, trans TTransport) { if err != nil { t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES) } - p.Flush() + p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin() if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES) @@ -280,7 +281,7 @@ func ReadWriteByte(t testing.TB, p TProtocol, trans TTransport) { if err != nil { t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES) } - err = p.Flush() + err = p.Flush(context.Background()) if err != nil { t.Errorf("%s: %T %T %q Error flushing list of bytes: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES) } @@ -320,7 +321,7 @@ func ReadWriteI16(t testing.TB, p TProtocol, trans TTransport) { p.WriteI16(v) } p.WriteListEnd() - p.Flush() + p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin() if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI16", p, trans, err, INT16_VALUES) @@ -357,7 +358,7 @@ func ReadWriteI32(t testing.TB, p TProtocol, trans TTransport) { p.WriteI32(v) } p.WriteListEnd() - p.Flush() + p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin() if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI32", p, trans, err, INT32_VALUES) @@ -393,7 +394,7 @@ func ReadWriteI64(t testing.TB, p TProtocol, trans TTransport) { p.WriteI64(v) } p.WriteListEnd() - p.Flush() + p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin() if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI64", p, trans, err, INT64_VALUES) @@ -429,7 +430,7 @@ func ReadWriteDouble(t testing.TB, p TProtocol, trans TTransport) { p.WriteDouble(v) } p.WriteListEnd() - p.Flush() + p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin() if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteDouble", p, trans, err, DOUBLE_VALUES) @@ -467,7 +468,7 @@ func ReadWriteString(t testing.TB, p TProtocol, trans TTransport) { p.WriteString(v) } p.WriteListEnd() - p.Flush() + p.Flush(context.Background()) thetype2, thelen2, err := p.ReadListBegin() if err != nil { t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteString", p, trans, err, STRING_VALUES) @@ -498,7 +499,7 @@ func ReadWriteString(t testing.TB, p TProtocol, trans TTransport) { func ReadWriteBinary(t testing.TB, p TProtocol, trans TTransport) { v := protocol_bdata p.WriteBinary(v) - p.Flush() + p.Flush(context.Background()) value, err := p.ReadBinary() if err != nil { t.Errorf("%s: %T %T Unable to read binary: %s", "ReadWriteBinary", p, trans, err.Error()) diff --git a/lib/go/thrift/serializer.go b/lib/go/thrift/serializer.go index 77122299909..1ff4d37545a 100644 --- a/lib/go/thrift/serializer.go +++ b/lib/go/thrift/serializer.go @@ -19,6 +19,10 @@ package thrift +import ( + "context" +) + type TSerializer struct { Transport *TMemoryBuffer Protocol TProtocol @@ -38,35 +42,35 @@ func NewTSerializer() *TSerializer { protocol} } -func (t *TSerializer) WriteString(msg TStruct) (s string, err error) { +func (t *TSerializer) WriteString(ctx context.Context, msg TStruct) (s string, err error) { t.Transport.Reset() if err = msg.Write(t.Protocol); err != nil { return } - if err = t.Protocol.Flush(); err != nil { + if err = t.Protocol.Flush(ctx); err != nil { return } - if err = t.Transport.Flush(); err != nil { + if err = t.Transport.Flush(ctx); err != nil { return } return t.Transport.String(), nil } -func (t *TSerializer) Write(msg TStruct) (b []byte, err error) { +func (t *TSerializer) Write(ctx context.Context, msg TStruct) (b []byte, err error) { t.Transport.Reset() if err = msg.Write(t.Protocol); err != nil { return } - if err = t.Protocol.Flush(); err != nil { + if err = t.Protocol.Flush(ctx); err != nil { return } - if err = t.Transport.Flush(); err != nil { + if err = t.Transport.Flush(ctx); err != nil { return } diff --git a/lib/go/thrift/serializer_test.go b/lib/go/thrift/serializer_test.go index 06d27a16b7b..32227ef4922 100644 --- a/lib/go/thrift/serializer_test.go +++ b/lib/go/thrift/serializer_test.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "errors" "fmt" "testing" @@ -88,7 +89,7 @@ func ProtocolTest1(test *testing.T, pf ProtocolFactory) (bool, error) { m.StringSet = make(map[string]struct{}, 5) m.E = 2 - s, err := t.WriteString(&m) + s, err := t.WriteString(context.Background(), &m) if err != nil { return false, errors.New(fmt.Sprintf("Unable to Serialize struct\n\t %s", err)) } @@ -122,7 +123,7 @@ func ProtocolTest2(test *testing.T, pf ProtocolFactory) (bool, error) { m.StringSet = make(map[string]struct{}, 5) m.E = 2 - s, err := t.WriteString(&m) + s, err := t.WriteString(context.Background(), &m) if err != nil { return false, errors.New(fmt.Sprintf("Unable to Serialize struct\n\t %s", err)) diff --git a/lib/go/thrift/simple_json_protocol.go b/lib/go/thrift/simple_json_protocol.go index 73533223182..88f569cc155 100644 --- a/lib/go/thrift/simple_json_protocol.go +++ b/lib/go/thrift/simple_json_protocol.go @@ -22,6 +22,7 @@ package thrift import ( "bufio" "bytes" + "context" "encoding/base64" "encoding/json" "fmt" @@ -552,7 +553,7 @@ func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, error) { return v, p.ParsePostValue() } -func (p *TSimpleJSONProtocol) Flush() (err error) { +func (p *TSimpleJSONProtocol) Flush(ctx context.Context) (err error) { return NewTProtocolException(p.writer.Flush()) } diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go index 8f0dcc9dfe2..49181ab1993 100644 --- a/lib/go/thrift/simple_json_protocol_test.go +++ b/lib/go/thrift/simple_json_protocol_test.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "encoding/base64" "encoding/json" "fmt" @@ -37,7 +38,7 @@ func TestWriteSimpleJSONProtocolBool(t *testing.T) { if e := p.WriteBool(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -63,7 +64,7 @@ func TestReadSimpleJSONProtocolBool(t *testing.T) { } else { trans.Write(JSON_FALSE) } - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBool() if e != nil { @@ -88,7 +89,7 @@ func TestWriteSimpleJSONProtocolByte(t *testing.T) { if e := p.WriteByte(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -110,7 +111,7 @@ func TestReadSimpleJSONProtocolByte(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadByte() if e != nil { @@ -135,7 +136,7 @@ func TestWriteSimpleJSONProtocolI16(t *testing.T) { if e := p.WriteI16(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -157,7 +158,7 @@ func TestReadSimpleJSONProtocolI16(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI16() if e != nil { @@ -182,7 +183,7 @@ func TestWriteSimpleJSONProtocolI32(t *testing.T) { if e := p.WriteI32(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -204,7 +205,7 @@ func TestReadSimpleJSONProtocolI32(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.Itoa(int(value))) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI32() if e != nil { @@ -228,7 +229,7 @@ func TestReadSimpleJSONProtocolI32Null(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI32() @@ -250,7 +251,7 @@ func TestWriteSimpleJSONProtocolI64(t *testing.T) { if e := p.WriteI64(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -272,7 +273,7 @@ func TestReadSimpleJSONProtocolI64(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(strconv.FormatInt(value, 10)) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI64() if e != nil { @@ -296,7 +297,7 @@ func TestReadSimpleJSONProtocolI64Null(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadI64() @@ -318,7 +319,7 @@ func TestWriteSimpleJSONProtocolDouble(t *testing.T) { if e := p.WriteDouble(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -355,7 +356,7 @@ func TestReadSimpleJSONProtocolDouble(t *testing.T) { p := NewTSimpleJSONProtocol(trans) n := NewNumericFromDouble(value) trans.WriteString(n.String()) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadDouble() if e != nil { @@ -394,7 +395,7 @@ func TestWriteSimpleJSONProtocolString(t *testing.T) { if e := p.WriteString(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -416,7 +417,7 @@ func TestReadSimpleJSONProtocolString(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(jsonQuote(value)) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadString() if e != nil { @@ -440,7 +441,7 @@ func TestReadSimpleJSONProtocolStringNull(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadString() if e != nil { @@ -464,7 +465,7 @@ func TestWriteSimpleJSONProtocolBinary(t *testing.T) { if e := p.WriteBinary(value); e != nil { t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) } - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error()) } s := trans.String() @@ -487,7 +488,7 @@ func TestReadSimpleJSONProtocolBinary(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(jsonQuote(b64String)) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() v, e := p.ReadBinary() if e != nil { @@ -516,7 +517,7 @@ func TestReadSimpleJSONProtocolBinaryNull(t *testing.T) { trans := NewTMemoryBuffer() p := NewTSimpleJSONProtocol(trans) trans.WriteString(value) - trans.Flush() + trans.Flush(context.Background()) s := trans.String() b, e := p.ReadBinary() v := string(b) @@ -542,7 +543,7 @@ func TestWriteSimpleJSONProtocolList(t *testing.T) { } } p.WriteListEnd() - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() @@ -596,7 +597,7 @@ func TestWriteSimpleJSONProtocolSet(t *testing.T) { } } p.WriteSetEnd() - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() @@ -653,7 +654,7 @@ func TestWriteSimpleJSONProtocolMap(t *testing.T) { } } p.WriteMapEnd() - if e := p.Flush(); e != nil { + if e := p.Flush(context.Background()); e != nil { t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error()) } str := trans.String() diff --git a/lib/go/thrift/socket.go b/lib/go/thrift/socket.go index 383b1fe3e97..8854279651f 100644 --- a/lib/go/thrift/socket.go +++ b/lib/go/thrift/socket.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "net" "time" ) @@ -148,7 +149,7 @@ func (p *TSocket) Write(buf []byte) (int, error) { return p.conn.Write(buf) } -func (p *TSocket) Flush() error { +func (p *TSocket) Flush(ctx context.Context) error { return nil } diff --git a/lib/go/thrift/ssl_socket.go b/lib/go/thrift/ssl_socket.go index c3bd72cc467..ba63377263a 100644 --- a/lib/go/thrift/ssl_socket.go +++ b/lib/go/thrift/ssl_socket.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "crypto/tls" "net" "time" @@ -158,7 +159,7 @@ func (p *TSSLSocket) Write(buf []byte) (int, error) { return p.conn.Write(buf) } -func (p *TSSLSocket) Flush() error { +func (p *TSSLSocket) Flush(ctx context.Context) error { return nil } diff --git a/lib/go/thrift/transport.go b/lib/go/thrift/transport.go index 70a85a84895..ba2738a8df1 100644 --- a/lib/go/thrift/transport.go +++ b/lib/go/thrift/transport.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "errors" "io" ) @@ -30,6 +31,10 @@ type Flusher interface { Flush() (err error) } +type ContextFlusher interface { + Flush(ctx context.Context) (err error) +} + type ReadSizeProvider interface { RemainingBytes() (num_bytes uint64) } @@ -37,7 +42,7 @@ type ReadSizeProvider interface { // Encapsulates the I/O layer type TTransport interface { io.ReadWriteCloser - Flusher + ContextFlusher ReadSizeProvider // Opens the transport for communication @@ -60,6 +65,6 @@ type TRichTransport interface { io.ByteReader io.ByteWriter stringWriter - Flusher + ContextFlusher ReadSizeProvider } diff --git a/lib/go/thrift/transport_test.go b/lib/go/thrift/transport_test.go index 864958a9da0..01278038efa 100644 --- a/lib/go/thrift/transport_test.go +++ b/lib/go/thrift/transport_test.go @@ -20,6 +20,7 @@ package thrift import ( + "context" "io" "net" "strconv" @@ -54,7 +55,7 @@ func TransportTest(t *testing.T, writeTrans TTransport, readTrans TTransport) { if err != nil { t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err) } - err = writeTrans.Flush() + err = writeTrans.Flush(context.Background()) if err != nil { t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err) } @@ -74,7 +75,7 @@ func TransportTest(t *testing.T, writeTrans TTransport, readTrans TTransport) { if err != nil { t.Fatalf("Transport %T cannot write binary data 2 of length %d: %s", writeTrans, len(transport_bdata), err) } - err = writeTrans.Flush() + err = writeTrans.Flush(context.Background()) if err != nil { t.Fatalf("Transport %T cannot flush write binary data 2: %s", writeTrans, err) } @@ -113,7 +114,7 @@ func TransportHeaderTest(t *testing.T, writeTrans TTransport, readTrans TTranspo if err != nil { t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err) } - err = writeTrans.Flush() + err = writeTrans.Flush(context.Background()) if err != nil { t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err) } diff --git a/lib/go/thrift/zlib_transport.go b/lib/go/thrift/zlib_transport.go index f2f07322217..f3d42673af9 100644 --- a/lib/go/thrift/zlib_transport.go +++ b/lib/go/thrift/zlib_transport.go @@ -21,6 +21,7 @@ package thrift import ( "compress/zlib" + "context" "io" "log" ) @@ -91,11 +92,11 @@ func (z *TZlibTransport) Close() error { } // Flush flushes the writer and its underlying transport. -func (z *TZlibTransport) Flush() error { +func (z *TZlibTransport) Flush(ctx context.Context) error { if err := z.writer.Flush(); err != nil { return err } - return z.transport.Flush() + return z.transport.Flush(ctx) } // IsOpen returns true if the transport is open diff --git a/test/go/Makefile.am b/test/go/Makefile.am index 6bc97f582c5..6da83394bea 100644 --- a/test/go/Makefile.am +++ b/test/go/Makefile.am @@ -18,9 +18,6 @@ # BUILT_SOURCES = gopath -if GOVERSION_LT_17 -COMPILER_EXTRAFLAG=",legacy_context" -endif THRIFTCMD = $(THRIFT) -out src/gen --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG) THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift @@ -37,7 +34,6 @@ gopath: $(THRIFT) ThriftTest.thrift mkdir -p src/gen $(THRIFTCMD) ThriftTest.thrift $(THRIFTCMD) ../StressTest.thrift - GOPATH=`pwd` $(GO) get golang.org/x/net/context GOPATH=`pwd` $(GO) get github.com/golang/mock/gomock || true sed -i 's/\"context\"/\"golang.org\/x\/net\/context\"/g' src/github.com/golang/mock/gomock/controller.go || true GOPATH=`pwd` $(GO) get github.com/golang/mock/gomock diff --git a/test/go/src/bin/stress/go17.go b/test/go/src/bin/stress/go17.go deleted file mode 100644 index 81f1ad8ee6b..00000000000 --- a/test/go/src/bin/stress/go17.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 main - -import ( - "context" - "sync/atomic" -) - -type handler struct{} - -func (h *handler) EchoVoid(ctx context.Context) (err error) { - atomic.AddInt64(&counter, 1) - return nil -} -func (h *handler) EchoByte(ctx context.Context, arg int8) (r int8, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoI32(ctx context.Context, arg int32) (r int32, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoI64(ctx context.Context, arg int64) (r int64, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoString(ctx context.Context, arg string) (r string, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoList(ctx context.Context, arg []int8) (r []int8, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoSet(ctx context.Context, arg map[int8]struct{}) (r map[int8]struct{}, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoMap(ctx context.Context, arg map[int8]int8) (r map[int8]int8, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} diff --git a/test/go/src/bin/stress/main.go b/test/go/src/bin/stress/main.go index e8e6b2a2072..f2e0f20730d 100644 --- a/test/go/src/bin/stress/main.go +++ b/test/go/src/bin/stress/main.go @@ -20,6 +20,7 @@ package main import ( + "context" "flag" "fmt" "gen/stress" @@ -216,3 +217,38 @@ func client(protocolFactory thrift.TProtocolFactory) { done.Done() } + +type handler struct{} + +func (h *handler) EchoVoid(ctx context.Context) (err error) { + atomic.AddInt64(&counter, 1) + return nil +} +func (h *handler) EchoByte(ctx context.Context, arg int8) (r int8, err error) { + atomic.AddInt64(&counter, 1) + return arg, nil +} +func (h *handler) EchoI32(ctx context.Context, arg int32) (r int32, err error) { + atomic.AddInt64(&counter, 1) + return arg, nil +} +func (h *handler) EchoI64(ctx context.Context, arg int64) (r int64, err error) { + atomic.AddInt64(&counter, 1) + return arg, nil +} +func (h *handler) EchoString(ctx context.Context, arg string) (r string, err error) { + atomic.AddInt64(&counter, 1) + return arg, nil +} +func (h *handler) EchoList(ctx context.Context, arg []int8) (r []int8, err error) { + atomic.AddInt64(&counter, 1) + return arg, nil +} +func (h *handler) EchoSet(ctx context.Context, arg map[int8]struct{}) (r map[int8]struct{}, err error) { + atomic.AddInt64(&counter, 1) + return arg, nil +} +func (h *handler) EchoMap(ctx context.Context, arg map[int8]int8) (r map[int8]int8, err error) { + atomic.AddInt64(&counter, 1) + return arg, nil +} diff --git a/test/go/src/bin/stress/pre_go17.go b/test/go/src/bin/stress/pre_go17.go deleted file mode 100644 index 07ae5c6a282..00000000000 --- a/test/go/src/bin/stress/pre_go17.go +++ /dev/null @@ -1,63 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 main - -import ( - "sync/atomic" - - "golang.org/x/net/context" -) - -type handler struct{} - -func (h *handler) EchoVoid(ctx context.Context) (err error) { - atomic.AddInt64(&counter, 1) - return nil -} -func (h *handler) EchoByte(ctx context.Context, arg int8) (r int8, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoI32(ctx context.Context, arg int32) (r int32, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoI64(ctx context.Context, arg int64) (r int64, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoString(ctx context.Context, arg string) (r string, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoList(ctx context.Context, arg []int8) (r []int8, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoSet(ctx context.Context, arg map[int8]struct{}) (r map[int8]struct{}, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} -func (h *handler) EchoMap(ctx context.Context, arg map[int8]int8) (r map[int8]int8, err error) { - atomic.AddInt64(&counter, 1) - return arg, nil -} diff --git a/test/go/src/bin/testclient/go17.go b/test/go/src/bin/testclient/go17.go deleted file mode 100644 index a6003a9174f..00000000000 --- a/test/go/src/bin/testclient/go17.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 main - -import "context" - -var defaultCtx = context.Background() diff --git a/test/go/src/bin/testclient/main.go b/test/go/src/bin/testclient/main.go index ab24cbfc744..20104f9e12e 100644 --- a/test/go/src/bin/testclient/main.go +++ b/test/go/src/bin/testclient/main.go @@ -21,6 +21,7 @@ package main import ( "common" + "context" "flag" "gen/thrifttest" t "log" @@ -60,6 +61,7 @@ var xxs = &thrifttest.Xtruct{ } var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "Xception"} +var defaultCtx = context.Background() func callEverything(client *thrifttest.ThriftTestClient) { var err error diff --git a/test/go/src/bin/testclient/pre_go17.go b/test/go/src/bin/testclient/pre_go17.go deleted file mode 100644 index 10a6fb8d932..00000000000 --- a/test/go/src/bin/testclient/pre_go17.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 main - -import "golang.org/x/net/context" - -var defaultCtx = context.Background() diff --git a/test/go/src/common/clientserver_test.go b/test/go/src/common/clientserver_test.go index c4cfd44f303..cb1abf775ca 100644 --- a/test/go/src/common/clientserver_test.go +++ b/test/go/src/common/clientserver_test.go @@ -20,6 +20,7 @@ package common import ( + "context" "errors" "gen/thrifttest" "reflect" @@ -95,6 +96,7 @@ var xxs = &thrifttest.Xtruct{ } var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "some"} +var defaultCtx = context.Background() func callEverythingWithMock(t *testing.T, client *thrifttest.ThriftTestClient, handler *MockThriftTest) { gomock.InOrder( diff --git a/test/go/src/common/context_test.go b/test/go/src/common/context_test.go new file mode 100644 index 00000000000..e64dbb9adb0 --- /dev/null +++ b/test/go/src/common/context_test.go @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 common + +import ( + "context" + "fmt" + "net" + "net/http" + "net/url" + "os" + "syscall" + "testing" + "thrift" + "time" +) + +type slowHttpHandler struct{} + +func (slowHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + time.Sleep(1 * time.Second) +} + +func TestHttpContextTimeout(t *testing.T) { + certPath = "../../../keys" + + unit := test_unit{"127.0.0.1", 9096, "", "http", "binary", false} + + server := &http.Server{Addr: unit.host + fmt.Sprintf(":%d", unit.port), Handler: slowHttpHandler{}} + go server.ListenAndServe() + + client, trans, err := StartClient(unit.host, unit.port, unit.domain_socket, unit.transport, unit.protocol, unit.ssl) + if err != nil { + t.Errorf("Unable to start client: %v", err) + return + } + defer trans.Close() + + unwrapErr := func(err error) error { + for { + switch err.(type) { + case thrift.TTransportException: + err = err.(thrift.TTransportException).Err() + case *url.Error: + err = err.(*url.Error).Err + case *net.OpError: + err = err.(*net.OpError).Err + case *os.SyscallError: + err = err.(*os.SyscallError).Err + default: + return err + } + } + } + + serverStartupDeadline := time.Now().Add(5 * time.Second) + for { + ctx, _ := context.WithTimeout(context.Background(), 50*time.Millisecond) + err = client.TestVoid(ctx) + err = unwrapErr(err) + if err != syscall.ECONNREFUSED || time.Now().After(serverStartupDeadline) { + break + } + time.Sleep(time.Millisecond) + } + + if err == nil { + t.Errorf("Request completed (should have timed out)") + return + } + + // We've got to switch on `err.Error()` here since go1.7 doesn't properly return + // `context.DeadlineExceeded` error and `http.errRequestCanceled` is not exported. + // See https://github.com/golang/go/issues/17711 + switch err.Error() { + case context.DeadlineExceeded.Error(), "net/http: request canceled": + // Expected error + default: + t.Errorf("Unexpected error: %s", err) + } +} diff --git a/test/go/src/common/go17.go b/test/go/src/common/go17.go deleted file mode 100644 index 9aca4075c74..00000000000 --- a/test/go/src/common/go17.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 common - -import "context" - -var defaultCtx = context.Background() diff --git a/test/go/src/common/pre_go17.go b/test/go/src/common/pre_go17.go deleted file mode 100644 index 6c14579d299..00000000000 --- a/test/go/src/common/pre_go17.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 common - -import "golang.org/x/net/context" - -var defaultCtx = context.Background() diff --git a/test/go/src/common/printing_handler.go b/test/go/src/common/printing_handler.go index c0a28626788..2b22d0c9773 100644 --- a/test/go/src/common/printing_handler.go +++ b/test/go/src/common/printing_handler.go @@ -1,5 +1,3 @@ -// +build !go1.7 - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -22,13 +20,12 @@ package common import ( + "context" + "encoding/hex" "errors" "fmt" - "encoding/hex" . "gen/thrifttest" "time" - - "golang.org/x/net/context" ) var PrintingHandler = &printingHandler{} @@ -280,11 +277,11 @@ func (p *printingHandler) TestMapMap(ctx context.Context, hello int32) (r map[in func (p *printingHandler) TestInsanity(ctx context.Context, argument *Insanity) (r map[UserId]map[Numberz]*Insanity, err error) { fmt.Printf("testInsanity()\n") r = make(map[UserId]map[Numberz]*Insanity) - r[1] = map[Numberz]*Insanity { + r[1] = map[Numberz]*Insanity{ 2: argument, 3: argument, } - r[2] = map[Numberz]*Insanity { + r[2] = map[Numberz]*Insanity{ 6: NewInsanity(), } return diff --git a/test/go/src/common/printing_handler_go17.go b/test/go/src/common/printing_handler_go17.go deleted file mode 100644 index 1efae8676c5..00000000000 --- a/test/go/src/common/printing_handler_go17.go +++ /dev/null @@ -1,386 +0,0 @@ -// +build go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 common - -import ( - "context" - "errors" - "fmt" - "encoding/hex" - . "gen/thrifttest" - "time" -) - -var PrintingHandler = &printingHandler{} - -type printingHandler struct{} - -// Prints "testVoid()" and returns nothing. -func (p *printingHandler) TestVoid(ctx context.Context) (err error) { - fmt.Println("testVoid()") - return nil -} - -// Prints 'testString("%s")' with thing as '%s' -// @param string thing - the string to print -// @return string - returns the string 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestString(ctx context.Context, thing string) (r string, err error) { - fmt.Printf("testString(\"%s\")\n", thing) - return thing, nil -} - -// Prints 'testBool("%t")' with thing as 'true' or 'false' -// @param bool thing - the bool to print -// @return bool - returns the bool 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestBool(ctx context.Context, thing bool) (r bool, err error) { - fmt.Printf("testBool(%t)\n", thing) - return thing, nil -} - -// Prints 'testByte("%d")' with thing as '%d' -// @param byte thing - the byte to print -// @return byte - returns the byte 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestByte(ctx context.Context, thing int8) (r int8, err error) { - fmt.Printf("testByte(%d)\n", thing) - return thing, nil -} - -// Prints 'testI32("%d")' with thing as '%d' -// @param i32 thing - the i32 to print -// @return i32 - returns the i32 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestI32(ctx context.Context, thing int32) (r int32, err error) { - fmt.Printf("testI32(%d)\n", thing) - return thing, nil -} - -// Prints 'testI64("%d")' with thing as '%d' -// @param i64 thing - the i64 to print -// @return i64 - returns the i64 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestI64(ctx context.Context, thing int64) (r int64, err error) { - fmt.Printf("testI64(%d)\n", thing) - return thing, nil -} - -// Prints 'testDouble("%f")' with thing as '%f' -// @param double thing - the double to print -// @return double - returns the double 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestDouble(ctx context.Context, thing float64) (r float64, err error) { - fmt.Printf("testDouble(%f)\n", thing) - return thing, nil -} - -// Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data -// @param []byte thing - the binary to print -// @return []byte - returns the binary 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestBinary(ctx context.Context, thing []byte) (r []byte, err error) { - fmt.Printf("testBinary(%s)\n", hex.EncodeToString(thing)) - return thing, nil -} - -// Prints 'testStruct("{%s}")' where thing has been formatted into a string of comma separated values -// @param Xtruct thing - the Xtruct to print -// @return Xtruct - returns the Xtruct 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestStruct(ctx context.Context, thing *Xtruct) (r *Xtruct, err error) { - fmt.Printf("testStruct({\"%s\", %d, %d, %d})\n", thing.StringThing, thing.ByteThing, thing.I32Thing, thing.I64Thing) - return thing, err -} - -// Prints 'testNest("{%s}")' where thing has been formatted into a string of the nested struct -// @param Xtruct2 thing - the Xtruct2 to print -// @return Xtruct2 - returns the Xtruct2 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestNest(ctx context.Context, nest *Xtruct2) (r *Xtruct2, err error) { - thing := nest.StructThing - fmt.Printf("testNest({%d, {\"%s\", %d, %d, %d}, %d})\n", nest.ByteThing, thing.StringThing, thing.ByteThing, thing.I32Thing, thing.I64Thing, nest.I32Thing) - return nest, nil -} - -// Prints 'testMap("{%s")' where thing has been formatted into a string of 'key => value' pairs -// separated by commas and new lines -// @param map thing - the map to print -// @return map - returns the map 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestMap(ctx context.Context, thing map[int32]int32) (r map[int32]int32, err error) { - fmt.Printf("testMap({") - first := true - for k, v := range thing { - if first { - first = false - } else { - fmt.Printf(", ") - } - fmt.Printf("%d => %d", k, v) - } - fmt.Printf("})\n") - return thing, nil -} - -// Prints 'testStringMap("{%s}")' where thing has been formatted into a string of 'key => value' pairs -// separated by commas and new lines -// @param map thing - the map to print -// @return map - returns the map 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestStringMap(ctx context.Context, thing map[string]string) (r map[string]string, err error) { - fmt.Printf("testStringMap({") - first := true - for k, v := range thing { - if first { - first = false - } else { - fmt.Printf(", ") - } - fmt.Printf("%s => %s", k, v) - } - fmt.Printf("})\n") - return thing, nil -} - -// Prints 'testSet("{%s}")' where thing has been formatted into a string of values -// separated by commas and new lines -// @param set thing - the set to print -// @return set - returns the set 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestSet(ctx context.Context, thing []int32) (r []int32, err error) { - fmt.Printf("testSet({") - first := true - for k, _ := range thing { - if first { - first = false - } else { - fmt.Printf(", ") - } - fmt.Printf("%d", k) - } - fmt.Printf("})\n") - return thing, nil -} - -// Prints 'testList("{%s}")' where thing has been formatted into a string of values -// separated by commas and new lines -// @param list thing - the list to print -// @return list - returns the list 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestList(ctx context.Context, thing []int32) (r []int32, err error) { - fmt.Printf("testList({") - for i, v := range thing { - if i != 0 { - fmt.Printf(", ") - } - fmt.Printf("%d", v) - } - fmt.Printf("})\n") - return thing, nil -} - -// Prints 'testEnum("%d")' where thing has been formatted into it's numeric value -// @param Numberz thing - the Numberz to print -// @return Numberz - returns the Numberz 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestEnum(ctx context.Context, thing Numberz) (r Numberz, err error) { - fmt.Printf("testEnum(%d)\n", thing) - return thing, nil -} - -// Prints 'testTypedef("%d")' with thing as '%d' -// @param UserId thing - the UserId to print -// @return UserId - returns the UserId 'thing' -// -// Parameters: -// - Thing -func (p *printingHandler) TestTypedef(ctx context.Context, thing UserId) (r UserId, err error) { - fmt.Printf("testTypedef(%d)\n", thing) - return thing, nil -} - -// Prints 'testMapMap("%d")' with hello as '%d' -// @param i32 hello - the i32 to print -// @return map> - returns a dictionary with these values: -// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, } -// -// Parameters: -// - Hello -func (p *printingHandler) TestMapMap(ctx context.Context, hello int32) (r map[int32]map[int32]int32, err error) { - fmt.Printf("testMapMap(%d)\n", hello) - - r = map[int32]map[int32]int32{ - -4: map[int32]int32{-4: -4, -3: -3, -2: -2, -1: -1}, - 4: map[int32]int32{4: 4, 3: 3, 2: 2, 1: 1}, - } - return -} - -// So you think you've got this all worked, out eh? -// -// Creates a the returned map with these values and prints it out: -// { 1 => { 2 => argument, -// 3 => argument, -// }, -// 2 => { 6 => , }, -// } -// @return map> - a map with the above values -// -// Parameters: -// - Argument -func (p *printingHandler) TestInsanity(ctx context.Context, argument *Insanity) (r map[UserId]map[Numberz]*Insanity, err error) { - fmt.Printf("testInsanity()\n") - r = make(map[UserId]map[Numberz]*Insanity) - r[1] = map[Numberz]*Insanity { - 2: argument, - 3: argument, - } - r[2] = map[Numberz]*Insanity { - 6: NewInsanity(), - } - return -} - -// Prints 'testMulti()' -// @param byte arg0 - -// @param i32 arg1 - -// @param i64 arg2 - -// @param map arg3 - -// @param Numberz arg4 - -// @param UserId arg5 - -// @return Xtruct - returns an Xtruct with StringThing = "Hello2, ByteThing = arg0, I32Thing = arg1 -// and I64Thing = arg2 -// -// Parameters: -// - Arg0 -// - Arg1 -// - Arg2 -// - Arg3 -// - Arg4 -// - Arg5 -func (p *printingHandler) TestMulti(ctx context.Context, arg0 int8, arg1 int32, arg2 int64, arg3 map[int16]string, arg4 Numberz, arg5 UserId) (r *Xtruct, err error) { - fmt.Printf("testMulti()\n") - r = NewXtruct() - - r.StringThing = "Hello2" - r.ByteThing = arg0 - r.I32Thing = arg1 - r.I64Thing = arg2 - return -} - -// Print 'testException(%s)' with arg as '%s' -// @param string arg - a string indication what type of exception to throw -// if arg == "Xception" throw Xception with errorCode = 1001 and message = arg -// elsen if arg == "TException" throw TException -// else do not throw anything -// -// Parameters: -// - Arg -func (p *printingHandler) TestException(ctx context.Context, arg string) (err error) { - fmt.Printf("testException(%s)\n", arg) - switch arg { - case "Xception": - e := NewXception() - e.ErrorCode = 1001 - e.Message = arg - return e - case "TException": - return errors.New("Just TException") - } - return -} - -// Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s' -// @param string arg - a string indication what type of exception to throw -// if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception" -// elsen if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and message = "This is an Xception2" -// else do not throw anything -// @return Xtruct - an Xtruct with StringThing = arg1 -// -// Parameters: -// - Arg0 -// - Arg1 -func (p *printingHandler) TestMultiException(ctx context.Context, arg0 string, arg1 string) (r *Xtruct, err error) { - fmt.Printf("testMultiException(%s, %s)\n", arg0, arg1) - switch arg0 { - - case "Xception": - e := NewXception() - e.ErrorCode = 1001 - e.Message = "This is an Xception" - return nil, e - case "Xception2": - e := NewXception2() - e.ErrorCode = 2002 - e.StructThing = NewXtruct() - e.StructThing.StringThing = "This is an Xception2" - return nil, e - default: - r = NewXtruct() - r.StringThing = arg1 - return - } -} - -// Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d' -// sleep 'secondsToSleep' -// Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d' -// @param i32 secondsToSleep - the number of seconds to sleep -// -// Parameters: -// - SecondsToSleep -func (p *printingHandler) TestOneway(ctx context.Context, secondsToSleep int32) (err error) { - fmt.Printf("testOneway(%d): Sleeping...\n", secondsToSleep) - time.Sleep(time.Second * time.Duration(secondsToSleep)) - fmt.Printf("testOneway(%d): done sleeping!\n", secondsToSleep) - return -} diff --git a/tutorial/go/Makefile.am b/tutorial/go/Makefile.am index a146d5c9fa9..87a8f5a71ed 100644 --- a/tutorial/go/Makefile.am +++ b/tutorial/go/Makefile.am @@ -17,10 +17,6 @@ # under the License. # -if GOVERSION_LT_17 -COMPILER_EXTRAFLAG=":legacy_context" -endif - gen-go/tutorial/calculator.go gen-go/shared/shared_service.go: $(top_srcdir)/tutorial/tutorial.thrift $(THRIFT) --gen go$(COMPILER_EXTRAFLAG) -r $< @@ -37,9 +33,6 @@ src/git.apache.org/thrift.git/lib/go/thrift: ln -sf $(realpath $(top_srcdir)/lib/go/thrift) src/git.apache.org/thrift.git/lib/go/thrift thirdparty-dep: - mkdir -p src/golang.org/x/net - GOPATH=`pwd`/gopath $(GO) get golang.org/x/net/context - ln -sf `pwd`/gopath/src/golang.org/x/net/context src/golang.org/x/net/context tutorialserver: all GOPATH=`pwd` $(GO) run src/*.go -server=true @@ -61,9 +54,6 @@ EXTRA_DIST = \ src/handler.go \ src/server.go \ src/main.go \ - src/go17.go \ - src/handler_go17.go \ - src/pre_go17.go \ server.crt \ server.key diff --git a/tutorial/go/src/client.go b/tutorial/go/src/client.go index 25616bf4ecc..1d658b9542f 100644 --- a/tutorial/go/src/client.go +++ b/tutorial/go/src/client.go @@ -20,6 +20,7 @@ package main */ import ( + "context" "crypto/tls" "fmt" "tutorial" @@ -27,6 +28,8 @@ import ( "git.apache.org/thrift.git/lib/go/thrift" ) +var defaultCtx = context.Background() + func handleClient(client *tutorial.CalculatorClient) (err error) { client.Ping(defaultCtx) fmt.Println("ping()") diff --git a/tutorial/go/src/handler.go b/tutorial/go/src/handler.go index 783b43267d4..5c0eed0060a 100644 --- a/tutorial/go/src/handler.go +++ b/tutorial/go/src/handler.go @@ -1,5 +1,3 @@ -// +build !go1.7 - package main /* @@ -22,12 +20,11 @@ package main */ import ( + "context" "fmt" "shared" "strconv" "tutorial" - - "golang.org/x/net/context" ) type CalculatorHandler struct { diff --git a/tutorial/go/src/handler_go17.go b/tutorial/go/src/handler_go17.go deleted file mode 100644 index d6752cc783e..00000000000 --- a/tutorial/go/src/handler_go17.go +++ /dev/null @@ -1,104 +0,0 @@ -// +build go1.7 - -package main - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -import ( - "context" - "fmt" - "shared" - "strconv" - "tutorial" -) - -type CalculatorHandler struct { - log map[int]*shared.SharedStruct -} - -func NewCalculatorHandler() *CalculatorHandler { - return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)} -} - -func (p *CalculatorHandler) Ping(ctx context.Context) (err error) { - fmt.Print("ping()\n") - return nil -} - -func (p *CalculatorHandler) Add(ctx context.Context, num1 int32, num2 int32) (retval17 int32, err error) { - fmt.Print("add(", num1, ",", num2, ")\n") - return num1 + num2, nil -} - -func (p *CalculatorHandler) Calculate(ctx context.Context, logid int32, w *tutorial.Work) (val int32, err error) { - fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n") - switch w.Op { - case tutorial.Operation_ADD: - val = w.Num1 + w.Num2 - break - case tutorial.Operation_SUBTRACT: - val = w.Num1 - w.Num2 - break - case tutorial.Operation_MULTIPLY: - val = w.Num1 * w.Num2 - break - case tutorial.Operation_DIVIDE: - if w.Num2 == 0 { - ouch := tutorial.NewInvalidOperation() - ouch.WhatOp = int32(w.Op) - ouch.Why = "Cannot divide by 0" - err = ouch - return - } - val = w.Num1 / w.Num2 - break - default: - ouch := tutorial.NewInvalidOperation() - ouch.WhatOp = int32(w.Op) - ouch.Why = "Unknown operation" - err = ouch - return - } - entry := shared.NewSharedStruct() - entry.Key = logid - entry.Value = strconv.Itoa(int(val)) - k := int(logid) - /* - oldvalue, exists := p.log[k] - if exists { - fmt.Print("Replacing ", oldvalue, " with ", entry, " for key ", k, "\n") - } else { - fmt.Print("Adding ", entry, " for key ", k, "\n") - } - */ - p.log[k] = entry - return val, err -} - -func (p *CalculatorHandler) GetStruct(ctx context.Context, key int32) (*shared.SharedStruct, error) { - fmt.Print("getStruct(", key, ")\n") - v, _ := p.log[int(key)] - return v, nil -} - -func (p *CalculatorHandler) Zip(ctx context.Context) (err error) { - fmt.Print("zip()\n") - return nil -} diff --git a/tutorial/go/src/pre_go17.go b/tutorial/go/src/pre_go17.go deleted file mode 100644 index 10a6fb8d932..00000000000 --- a/tutorial/go/src/pre_go17.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build !go1.7 - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 main - -import "golang.org/x/net/context" - -var defaultCtx = context.Background()