THRIFT-4448: Golang: do something with context.Context. Remove Go1.6 compatibility.

Client: go

This closes #1459
This commit is contained in:
John Boiles 2018-01-05 14:37:05 -08:00 committed by James E. King III
parent 3ae304268e
commit 5785279e2e
74 changed files with 407 additions and 1569 deletions

View File

@ -156,7 +156,7 @@ The Language/Library Levels indicate the minimum and maximum versions that are u
<td align=left><a href="lib/go/README.md">Go</a></td> <td align=left><a href="lib/go/README.md">Go</a></td>
<!-- Since -----------------><td>0.7.0</td> <!-- Since -----------------><td>0.7.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td> <!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>1.6.2</td><td>1.8.3</td> <!-- Language Levels -------><td>1.7.6</td><td>1.9.4</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td> <!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td> <!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td> <!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>

View File

@ -148,7 +148,7 @@ Last updated: October 1, 2017
| delphi | | | Not in CI | | delphi | | | Not in CI |
| dotnet | 2.1.4 | 2.1.4 | v2.1.4 SDK uses v2.0.5 Runtime | | dotnet | 2.1.4 | 2.1.4 | v2.1.4 SDK uses v2.0.5 Runtime |
| erlang | 18.3 | 20.0.4 | | | erlang | 18.3 | 20.0.4 | |
| go | 1.6.2 | 1.8.3 | | | go | 1.7.6 | 1.9.4 | THRIFT-4516: avoid 1.10 |
| haskell | 7.10.3 | 8.0.2 | | | haskell | 7.10.3 | 8.0.2 | |
| haxe | 3.2.1 | 3.4.4 | THRIFT-4352: avoid 3.4.2 | | haxe | 3.2.1 | 3.4.4 | THRIFT-4352: avoid 3.4.2 |
| java | 1.8.0_151 | 1.8.0_151 | | | java | 1.8.0_151 | 1.8.0_151 | |
@ -164,5 +164,3 @@ Last updated: October 1, 2017
| rust | 1.17.0 | 1.21.0 | | | rust | 1.17.0 | 1.21.0 | |
| smalltalk | | | Not in CI | | smalltalk | | | Not in CI |
| swift | | | Not in CI | | swift | | | Not in CI |

View File

@ -18,6 +18,7 @@
# - dart: does not come with Ubuntu # - dart: does not come with Ubuntu
# - dotnet: does not come with Ubuntu # - dotnet: does not come with Ubuntu
# - haxe: version 3.4.2 that comes with Ubuntu cores in our CI build # - haxe: version 3.4.2 that comes with Ubuntu cores in our CI build
# - go: xenial comes with 1.8, we want the latest (supported)
# - nodejs: want v8, Ubuntu comes with v6 # - nodejs: want v8, Ubuntu comes with v6
# #
@ -140,10 +141,15 @@ RUN apt-get install -y --no-install-recommends \
`# GlibC dependencies` \ `# GlibC dependencies` \
libglib2.0-dev libglib2.0-dev
RUN apt-get install -y --no-install-recommends \ # golang
`# golang (go) dependencies` \ ENV GOLANG_VERSION 1.9.4
golang-go \ ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
golang-race-detector-runtime ENV GOLANG_DOWNLOAD_SHA256 15b0937615809f87321a457bb1265f946f9f6e736c563d6c5e0bd2c22e44f779
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 \ RUN apt-get install -y --no-install-recommends \
`# Haskell dependencies` \ `# Haskell dependencies` \

View File

@ -113,9 +113,15 @@ RUN apt-get install -y --no-install-recommends \
`# GlibC dependencies` \ `# GlibC dependencies` \
libglib2.0-dev libglib2.0-dev
RUN apt-get install -y --no-install-recommends \ # golang
`# golang (go) dependencies` \ ENV GOLANG_VERSION 1.7.6
golang-go 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 \ RUN apt-get install -y --no-install-recommends \
`# Haskell dependencies` \ `# Haskell dependencies` \

View File

@ -15,7 +15,9 @@
# Using all stock Ubuntu Xenial packaging except for: # Using all stock Ubuntu Xenial packaging except for:
# - d: does not come with Ubuntu so we're installing 2.073.2 for coverage # - d: does not come with Ubuntu so we're installing 2.073.2 for coverage
# - dart: does not come with Ubuntu so we're installing 1.22.1 for coverage # - dart: does not come with Ubuntu so we're installing 1.22.1 for coverage
# - nodejs: Ubuntu comes with 4.2.6 which exits LTS April 2018, so we're installing 6.x # - dotnet: does not come with Ubuntu
# - go: Xenial comes with 1.6, but we need 1.7 or later
# - nodejs: Xenial comes with 4.2.6 which exits LTS April 2018, so we're installing 6.x
# #
FROM buildpack-deps:xenial-scm FROM buildpack-deps:xenial-scm
@ -138,10 +140,15 @@ RUN apt-get install -y --no-install-recommends \
`# GlibC dependencies` \ `# GlibC dependencies` \
libglib2.0-dev libglib2.0-dev
RUN apt-get install -y --no-install-recommends \ # golang
`# golang (go) dependencies` \ ENV GOLANG_VERSION 1.7.6
golang-go \ ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
golang-race-detector-runtime 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 \ RUN apt-get install -y --no-install-recommends \
`# Haskell dependencies` \ `# Haskell dependencies` \

View File

@ -81,7 +81,6 @@ public:
gen_package_prefix_ = ""; gen_package_prefix_ = "";
package_flag = ""; package_flag = "";
read_write_private_ = false; read_write_private_ = false;
legacy_context_ = false;
ignore_initialisms_ = false; ignore_initialisms_ = false;
for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) { for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
if( iter->first.compare("package_prefix") == 0) { if( iter->first.compare("package_prefix") == 0) {
@ -92,8 +91,6 @@ public:
package_flag = (iter->second); package_flag = (iter->second);
} else if( iter->first.compare("read_write_private") == 0) { } else if( iter->first.compare("read_write_private") == 0) {
read_write_private_ = true; read_write_private_ = true;
} else if( iter->first.compare("legacy_context") == 0) {
legacy_context_ = true;
} else if( iter->first.compare("ignore_initialisms") == 0) { } else if( iter->first.compare("ignore_initialisms") == 0) {
ignore_initialisms_ = true; ignore_initialisms_ = true;
} else { } else {
@ -287,7 +284,6 @@ private:
std::string gen_package_prefix_; std::string gen_package_prefix_;
std::string gen_thrift_import_; std::string gen_thrift_import_;
bool read_write_private_; bool read_write_private_;
bool legacy_context_;
bool ignore_initialisms_; bool ignore_initialisms_;
/** /**
@ -875,16 +871,10 @@ string t_go_generator::go_imports_begin(bool consts) {
"\t\"database/sql/driver\"\n" "\t\"database/sql/driver\"\n"
"\t\"errors\"\n"; "\t\"errors\"\n";
} }
if (legacy_context_) {
extra +=
"\t\"golang.org/x/net/context\"\n";
} else {
extra +=
"\t\"context\"\n";
}
return string( return string(
"import (\n" "import (\n"
"\t\"bytes\"\n" "\t\"bytes\"\n"
"\t\"context\"\n"
"\t\"reflect\"\n" "\t\"reflect\"\n"
+ extra + + extra +
"\t\"fmt\"\n" "\t\"fmt\"\n"
@ -2073,9 +2063,6 @@ void t_go_generator::generate_service_remote(t_service* tservice) {
string unused_protection; string unused_protection;
string ctxPackage = "context"; string ctxPackage = "context";
if (legacy_context_) {
ctxPackage = "golang.org/x/net/context";
}
f_remote << go_autogen_comment(); f_remote << go_autogen_comment();
f_remote << indent() << "package main" << endl << endl; f_remote << indent() << "package main" << endl << endl;
@ -2602,7 +2589,7 @@ void t_go_generator::generate_service_server(t_service* tservice) {
f_types_ << indent() << " oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId)" << endl; f_types_ << indent() << " oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId)" << endl;
f_types_ << indent() << " " << x << ".Write(oprot)" << endl; f_types_ << indent() << " " << x << ".Write(oprot)" << endl;
f_types_ << indent() << " oprot.WriteMessageEnd()" << 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() << " return false, " << x << endl;
f_types_ << indent() << "" << endl; f_types_ << indent() << "" << endl;
f_types_ << indent() << "}" << endl << endl; f_types_ << indent() << "}" << endl << endl;
@ -2667,7 +2654,7 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function*
<< "\", thrift.EXCEPTION, seqId)" << endl; << "\", thrift.EXCEPTION, seqId)" << endl;
f_types_ << indent() << " x.Write(oprot)" << endl; f_types_ << indent() << " x.Write(oprot)" << endl;
f_types_ << indent() << " oprot.WriteMessageEnd()" << 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() << " return false, err" << endl;
f_types_ << indent() << "}" << endl << endl; f_types_ << indent() << "}" << endl << endl;
@ -2735,7 +2722,7 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function*
<< "\", thrift.EXCEPTION, seqId)" << endl; << "\", thrift.EXCEPTION, seqId)" << endl;
f_types_ << indent() << " x.Write(oprot)" << endl; f_types_ << indent() << " x.Write(oprot)" << endl;
f_types_ << indent() << " oprot.WriteMessageEnd()" << 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; f_types_ << indent() << " return true, err2" << endl;
@ -2772,7 +2759,7 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function*
<< endl; << endl;
f_types_ << indent() << " err = err2" << endl; f_types_ << indent() << " err = err2" << endl;
f_types_ << indent() << "}" << 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() << " err = err2" << endl;
f_types_ << indent() << "}" << endl; f_types_ << indent() << "}" << endl;
f_types_ << indent() << "if err != nil {" << endl; f_types_ << indent() << "if err != nil {" << endl;
@ -3668,6 +3655,4 @@ THRIFT_REGISTER_GENERATOR(go, "Go",
" ignore_initialisms\n" " ignore_initialisms\n"
" Disable automatic spelling correction of initialisms (e.g. \"URL\")\n" \ " Disable automatic spelling correction of initialisms (e.g. \"URL\")\n" \
" read_write_private\n" " read_write_private\n"
" Make read/write methods private, default is public Read/Write\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")

View File

@ -31,14 +31,12 @@ install:
@echo '##############################################################' @echo '##############################################################'
check-local: check-local:
GOPATH=`pwd` $(GO) get golang.org/x/net/context
GOPATH=`pwd` $(GO) test -race ./thrift GOPATH=`pwd` $(GO) test -race ./thrift
clean-local: clean-local:
$(RM) -rf pkg $(RM) -rf pkg
all-local: all-local:
GOPATH=`pwd` $(GO) get golang.org/x/net/context
GOPATH=`pwd` $(GO) build ./thrift GOPATH=`pwd` $(GO) build ./thrift
EXTRA_DIST = \ EXTRA_DIST = \

View File

@ -24,6 +24,8 @@ under the License.
Using Thrift with Go Using Thrift with Go
==================== ====================
Thrift supports Go 1.7+
In following Go conventions, we recommend you use the 'go' tool to install In following Go conventions, we recommend you use the 'go' tool to install
Thrift for go. Thrift for go.

View File

@ -17,10 +17,6 @@
# under the License. # under the License.
# #
if GOVERSION_LT_17
COMPILER_EXTRAFLAG=",legacy_context"
endif
THRIFTARGS = -out gopath/src/ --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG) THRIFTARGS = -out gopath/src/ --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG)
THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift
@ -59,7 +55,6 @@ gopath: $(THRIFT) $(THRIFTTEST) \
$(THRIFT) $(THRIFTARGS) InitialismsTest.thrift $(THRIFT) $(THRIFTARGS) InitialismsTest.thrift
$(THRIFT) $(THRIFTARGS),read_write_private DontExportRWTest.thrift $(THRIFT) $(THRIFTARGS),read_write_private DontExportRWTest.thrift
$(THRIFT) $(THRIFTARGS),ignore_initialisms IgnoreInitialismsTest.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 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 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 GOPATH=`pwd`/gopath $(GO) get github.com/golang/mock/gomock

View File

@ -20,6 +20,7 @@
package tests package tests
import ( import (
"context"
"errors" "errors"
"errortest" "errortest"
"testing" "testing"
@ -212,7 +213,7 @@ func prepareClientCallReply(protocol *MockTProtocol, failAt int, failWith error)
if failAt == 25 { if failAt == 25 {
err = failWith err = failWith
} }
last = protocol.EXPECT().Flush().Return(err).After(last) last = protocol.EXPECT().Flush(context.Background()).Return(err).After(last)
if failAt == 25 { if failAt == 25 {
return true return true
} }
@ -536,7 +537,7 @@ func prepareClientCallException(protocol *MockTProtocol, failAt int, failWith er
last = protocol.EXPECT().WriteFieldStop().After(last) last = protocol.EXPECT().WriteFieldStop().After(last)
last = protocol.EXPECT().WriteStructEnd().After(last) last = protocol.EXPECT().WriteStructEnd().After(last)
last = protocol.EXPECT().WriteMessageEnd().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. // Reading the exception, might fail.
if failAt == 0 { if failAt == 0 {
@ -704,7 +705,7 @@ func TestClientSeqIdMismatch(t *testing.T) {
protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteFieldStop(),
protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteStructEnd(),
protocol.EXPECT().WriteMessageEnd(), protocol.EXPECT().WriteMessageEnd(),
protocol.EXPECT().Flush(), protocol.EXPECT().Flush(context.Background()),
protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil), protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil),
) )
@ -735,7 +736,7 @@ func TestClientSeqIdMismatchLegeacy(t *testing.T) {
protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteFieldStop(),
protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteStructEnd(),
protocol.EXPECT().WriteMessageEnd(), protocol.EXPECT().WriteMessageEnd(),
protocol.EXPECT().Flush(), protocol.EXPECT().Flush(context.Background()),
protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil), protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.REPLY, int32(2), nil),
) )
@ -764,7 +765,7 @@ func TestClientWrongMethodName(t *testing.T) {
protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteFieldStop(),
protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteStructEnd(),
protocol.EXPECT().WriteMessageEnd(), protocol.EXPECT().WriteMessageEnd(),
protocol.EXPECT().Flush(), protocol.EXPECT().Flush(context.Background()),
protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil), protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil),
) )
@ -795,7 +796,7 @@ func TestClientWrongMethodNameLegacy(t *testing.T) {
protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteFieldStop(),
protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteStructEnd(),
protocol.EXPECT().WriteMessageEnd(), protocol.EXPECT().WriteMessageEnd(),
protocol.EXPECT().Flush(), protocol.EXPECT().Flush(context.Background()),
protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil), protocol.EXPECT().ReadMessageBegin().Return("unknown", thrift.REPLY, int32(1), nil),
) )
@ -824,7 +825,7 @@ func TestClientWrongMessageType(t *testing.T) {
protocol.EXPECT().WriteFieldStop(), protocol.EXPECT().WriteFieldStop(),
protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteStructEnd(),
protocol.EXPECT().WriteMessageEnd(), protocol.EXPECT().WriteMessageEnd(),
protocol.EXPECT().Flush(), protocol.EXPECT().Flush(context.Background()),
protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil), 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().WriteFieldStop(),
protocol.EXPECT().WriteStructEnd(), protocol.EXPECT().WriteStructEnd(),
protocol.EXPECT().WriteMessageEnd(), protocol.EXPECT().WriteMessageEnd(),
protocol.EXPECT().Flush(), protocol.EXPECT().Flush(context.Background()),
protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil), protocol.EXPECT().ReadMessageBegin().Return("testString", thrift.INVALID_TMESSAGE_TYPE, int32(1), nil),
) )

View File

@ -1,5 +1,3 @@
// +build go1.7
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
@ -19,8 +17,10 @@
* under the License. * under the License.
*/ */
package main package tests
import "context" import (
"context"
)
var defaultCtx = context.Background() var defaultCtx = context.Background()

View File

@ -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 }

View File

@ -20,6 +20,7 @@
package tests package tests
import ( import (
"context"
"multiplexedprotocoltest" "multiplexedprotocoltest"
"net" "net"
"testing" "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) { func createTransport(addr net.Addr) (thrift.TTransport, error) {
socket := thrift.NewTSocketFromAddrTimeout(addr, TIMEOUT) socket := thrift.NewTSocketFromAddrTimeout(addr, TIMEOUT)
transport := thrift.NewTFramedTransport(socket) transport := thrift.NewTFramedTransport(socket)

View File

@ -20,6 +20,8 @@
package tests package tests
import ( import (
"context"
"fmt"
"net" "net"
"onewaytest" "onewaytest"
"testing" "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 const TIMEOUT = time.Second
var addr net.Addr var addr net.Addr

View File

@ -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 }

View File

@ -23,6 +23,7 @@
package tests package tests
import ( import (
"context"
thrift "thrift" thrift "thrift"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
@ -49,13 +50,13 @@ func (_m *MockTProtocol) EXPECT() *_MockTProtocolRecorder {
return _m.recorder return _m.recorder
} }
func (_m *MockTProtocol) Flush() error { func (_m *MockTProtocol) Flush(ctx context.Context) error {
ret := _m.ctrl.Call(_m, "Flush") ret := _m.ctrl.Call(_m, "Flush")
ret0, _ := ret[0].(error) ret0, _ := ret[0].(error)
return ret0 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") return _mr.mock.ctrl.RecordCall(_mr.mock, "Flush")
} }

View File

@ -1,5 +1,3 @@
// +build !go1.7
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
@ -22,12 +20,11 @@
package tests package tests
import ( import (
"context"
"errors" "errors"
"thrift" "thrift"
"thrifttest" "thrifttest"
"time" "time"
"golang.org/x/net/context"
) )
type SecondServiceHandler struct { type SecondServiceHandler struct {

View File

@ -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
}

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"bytes" "bytes"
"context"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
@ -457,8 +458,8 @@ func (p *TBinaryProtocol) ReadBinary() ([]byte, error) {
return buf, NewTProtocolException(err) return buf, NewTProtocolException(err)
} }
func (p *TBinaryProtocol) Flush() (err error) { func (p *TBinaryProtocol) Flush(ctx context.Context) (err error) {
return NewTProtocolException(p.trans.Flush()) return NewTProtocolException(p.trans.Flush(ctx))
} }
func (p *TBinaryProtocol) Skip(fieldType TType) (err error) { func (p *TBinaryProtocol) Skip(fieldType TType) (err error) {

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"bufio" "bufio"
"context"
) )
type TBufferedTransportFactory struct { type TBufferedTransportFactory struct {
@ -78,12 +79,12 @@ func (p *TBufferedTransport) Write(b []byte) (int, error) {
return n, err return n, err
} }
func (p *TBufferedTransport) Flush() error { func (p *TBufferedTransport) Flush(ctx context.Context) error {
if err := p.ReadWriter.Flush(); err != nil { if err := p.ReadWriter.Flush(); err != nil {
p.ReadWriter.Writer.Reset(p.tp) p.ReadWriter.Writer.Reset(p.tp)
return err return err
} }
return p.tp.Flush() return p.tp.Flush(ctx)
} }
func (p *TBufferedTransport) RemainingBytes() (num_bytes uint64) { func (p *TBufferedTransport) RemainingBytes() (num_bytes uint64) {

View File

@ -1,6 +1,13 @@
package thrift package thrift
import "fmt" import (
"context"
"fmt"
)
type TClient interface {
Call(ctx context.Context, method string, args, result TStruct) error
}
type TStandardClient struct { type TStandardClient struct {
seqId int32 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 { if err := oprot.WriteMessageBegin(method, CALL, seqId); err != nil {
return err return err
} }
@ -26,7 +33,7 @@ func (p *TStandardClient) Send(oprot TProtocol, seqId int32, method string, args
if err := oprot.WriteMessageEnd(); err != nil { if err := oprot.WriteMessageEnd(); err != nil {
return err return err
} }
return oprot.Flush() return oprot.Flush(ctx)
} }
func (p *TStandardClient) Recv(iprot TProtocol, seqId int32, method string, result TStruct) error { 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() 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++ p.seqId++
seqId := 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 return err
} }

View File

@ -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)
}

View File

@ -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)
}

View File

@ -1,5 +1,3 @@
// +build go1.7
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file

View File

@ -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)
}

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io" "io"
@ -599,8 +600,8 @@ func (p *TCompactProtocol) ReadBinary() (value []byte, err error) {
return buf, NewTProtocolException(e) return buf, NewTProtocolException(e)
} }
func (p *TCompactProtocol) Flush() (err error) { func (p *TCompactProtocol) Flush(ctx context.Context) (err error) {
return NewTProtocolException(p.trans.Flush()) return NewTProtocolException(p.trans.Flush(ctx))
} }
func (p *TCompactProtocol) Skip(fieldType TType) (err error) { func (p *TCompactProtocol) Skip(fieldType TType) (err error) {

View File

@ -1,5 +1,3 @@
// +build go1.7
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"log" "log"
) )
@ -258,8 +259,8 @@ func (tdp *TDebugProtocol) Skip(fieldType TType) (err error) {
log.Printf("%sSkip(fieldType=%#v) (err=%#v)", tdp.LogPrefix, fieldType, err) log.Printf("%sSkip(fieldType=%#v) (err=%#v)", tdp.LogPrefix, fieldType, err)
return return
} }
func (tdp *TDebugProtocol) Flush() (err error) { func (tdp *TDebugProtocol) Flush(ctx context.Context) (err error) {
err = tdp.Delegate.Flush() err = tdp.Delegate.Flush(ctx)
log.Printf("%sFlush() (err=%#v)", tdp.LogPrefix, err) log.Printf("%sFlush() (err=%#v)", tdp.LogPrefix, err)
return return
} }

View File

@ -22,6 +22,7 @@ package thrift
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"context"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io" "io"
@ -135,7 +136,7 @@ func (p *TFramedTransport) WriteString(s string) (n int, err error) {
return p.buf.WriteString(s) return p.buf.WriteString(s)
} }
func (p *TFramedTransport) Flush() error { func (p *TFramedTransport) Flush(ctx context.Context) error {
size := p.buf.Len() size := p.buf.Len()
buf := p.buffer[:4] buf := p.buffer[:4]
binary.BigEndian.PutUint32(buf, uint32(size)) binary.BigEndian.PutUint32(buf, uint32(size))
@ -151,7 +152,7 @@ func (p *TFramedTransport) Flush() error {
return NewTTransportExceptionFromError(err) return NewTTransportExceptionFromError(err)
} }
} }
err = p.transport.Flush() err = p.transport.Flush(ctx)
return NewTTransportExceptionFromError(err) return NewTTransportExceptionFromError(err)
} }

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"bytes" "bytes"
"context"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@ -181,7 +182,7 @@ func (p *THttpClient) WriteString(s string) (n int, err error) {
return p.requestBuffer.WriteString(s) 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. // Close any previous response body to avoid leaking connections.
p.closeResponse() p.closeResponse()
@ -190,6 +191,9 @@ func (p *THttpClient) Flush() error {
return NewTTransportExceptionFromError(err) return NewTTransportExceptionFromError(err)
} }
req.Header = p.header req.Header = p.header
if ctx != nil {
req = req.WithContext(ctx)
}
response, err := p.client.Do(req) response, err := p.client.Do(req)
if err != nil { if err != nil {
return NewTTransportExceptionFromError(err) return NewTTransportExceptionFromError(err)

View File

@ -26,6 +26,18 @@ import (
"strings" "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. // gz transparently compresses the HTTP response if the client supports it.
func gz(handler http.HandlerFunc) http.HandlerFunc { func gz(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {

View File

@ -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))
})
}

View File

@ -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))
})
}

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"bufio" "bufio"
"context"
"io" "io"
) )
@ -138,7 +139,7 @@ func (p *StreamTransport) Close() error {
} }
// Flushes the underlying output stream if not null. // 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 { if p.Writer == nil {
return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream") return NewTTransportException(NOT_OPEN, "Cannot flush null outputStream")
} }

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
) )
@ -438,10 +439,10 @@ func (p *TJSONProtocol) ReadBinary() ([]byte, error) {
return v, p.ParsePostValue() return v, p.ParsePostValue()
} }
func (p *TJSONProtocol) Flush() (err error) { func (p *TJSONProtocol) Flush(ctx context.Context) (err error) {
err = p.writer.Flush() err = p.writer.Flush()
if err == nil { if err == nil {
err = p.trans.Flush() err = p.trans.Flush(ctx)
} }
return NewTProtocolException(err) return NewTProtocolException(err)
} }

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -36,7 +37,7 @@ func TestWriteJSONProtocolBool(t *testing.T) {
if e := p.WriteBool(value); e != nil { if e := p.WriteBool(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -68,7 +69,7 @@ func TestReadJSONProtocolBool(t *testing.T) {
} else { } else {
trans.Write([]byte{'0'}) // not JSON_FALSE trans.Write([]byte{'0'}) // not JSON_FALSE
} }
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadBool() v, e := p.ReadBool()
if e != nil { if e != nil {
@ -94,7 +95,7 @@ func TestWriteJSONProtocolByte(t *testing.T) {
if e := p.WriteByte(value); e != nil { if e := p.WriteByte(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -116,7 +117,7 @@ func TestReadJSONProtocolByte(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTJSONProtocol(trans) p := NewTJSONProtocol(trans)
trans.WriteString(strconv.Itoa(int(value))) trans.WriteString(strconv.Itoa(int(value)))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadByte() v, e := p.ReadByte()
if e != nil { if e != nil {
@ -141,7 +142,7 @@ func TestWriteJSONProtocolI16(t *testing.T) {
if e := p.WriteI16(value); e != nil { if e := p.WriteI16(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -163,7 +164,7 @@ func TestReadJSONProtocolI16(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTJSONProtocol(trans) p := NewTJSONProtocol(trans)
trans.WriteString(strconv.Itoa(int(value))) trans.WriteString(strconv.Itoa(int(value)))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI16() v, e := p.ReadI16()
if e != nil { if e != nil {
@ -188,7 +189,7 @@ func TestWriteJSONProtocolI32(t *testing.T) {
if e := p.WriteI32(value); e != nil { if e := p.WriteI32(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -210,7 +211,7 @@ func TestReadJSONProtocolI32(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTJSONProtocol(trans) p := NewTJSONProtocol(trans)
trans.WriteString(strconv.Itoa(int(value))) trans.WriteString(strconv.Itoa(int(value)))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI32() v, e := p.ReadI32()
if e != nil { if e != nil {
@ -235,7 +236,7 @@ func TestWriteJSONProtocolI64(t *testing.T) {
if e := p.WriteI64(value); e != nil { if e := p.WriteI64(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -257,7 +258,7 @@ func TestReadJSONProtocolI64(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTJSONProtocol(trans) p := NewTJSONProtocol(trans)
trans.WriteString(strconv.FormatInt(value, 10)) trans.WriteString(strconv.FormatInt(value, 10))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI64() v, e := p.ReadI64()
if e != nil { if e != nil {
@ -282,7 +283,7 @@ func TestWriteJSONProtocolDouble(t *testing.T) {
if e := p.WriteDouble(value); e != nil { if e := p.WriteDouble(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -319,7 +320,7 @@ func TestReadJSONProtocolDouble(t *testing.T) {
p := NewTJSONProtocol(trans) p := NewTJSONProtocol(trans)
n := NewNumericFromDouble(value) n := NewNumericFromDouble(value)
trans.WriteString(n.String()) trans.WriteString(n.String())
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadDouble() v, e := p.ReadDouble()
if e != nil { if e != nil {
@ -358,7 +359,7 @@ func TestWriteJSONProtocolString(t *testing.T) {
if e := p.WriteString(value); e != nil { if e := p.WriteString(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -380,7 +381,7 @@ func TestReadJSONProtocolString(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTJSONProtocol(trans) p := NewTJSONProtocol(trans)
trans.WriteString(jsonQuote(value)) trans.WriteString(jsonQuote(value))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadString() v, e := p.ReadString()
if e != nil { if e != nil {
@ -409,7 +410,7 @@ func TestWriteJSONProtocolBinary(t *testing.T) {
if e := p.WriteBinary(value); e != nil { if e := p.WriteBinary(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -441,7 +442,7 @@ func TestReadJSONProtocolBinary(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTJSONProtocol(trans) p := NewTJSONProtocol(trans)
trans.WriteString(jsonQuote(b64String)) trans.WriteString(jsonQuote(b64String))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadBinary() v, e := p.ReadBinary()
if e != nil { if e != nil {
@ -474,7 +475,7 @@ func TestWriteJSONProtocolList(t *testing.T) {
} }
} }
p.WriteListEnd() 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()) t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
} }
str := trans.String() str := trans.String()
@ -528,7 +529,7 @@ func TestWriteJSONProtocolSet(t *testing.T) {
} }
} }
p.WriteSetEnd() 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()) t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
} }
str := trans.String() str := trans.String()
@ -585,7 +586,7 @@ func TestWriteJSONProtocolMap(t *testing.T) {
} }
} }
p.WriteMapEnd() 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()) t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
} }
str := trans.String() str := trans.String()

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"bytes" "bytes"
"context"
) )
// Memory buffer-based implementation of the TTransport interface. // 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 // Flushing a memory buffer is a no-op
func (p *TMemoryBuffer) Flush() error { func (p *TMemoryBuffer) Flush(ctx context.Context) error {
return nil return nil
} }

View File

@ -19,6 +19,12 @@
package thrift package thrift
import (
"context"
"fmt"
"strings"
)
/* /*
TMultiplexedProtocol is a protocol-independent concrete decorator TMultiplexedProtocol is a protocol-independent concrete decorator
that allows a Thrift client to communicate with a multiplexing Thrift server, 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 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 //Protocol that use stored message for ReadMessageBegin
type storedMessageProtocol struct { type storedMessageProtocol struct {
TProtocol TProtocol

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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()

View File

@ -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)
}

View File

@ -19,6 +19,18 @@
package thrift 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 // The default processor factory just returns a singleton
// instance. // instance.
type TProcessorFactory interface { type TProcessorFactory interface {

View File

@ -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)
}

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
) )
@ -74,7 +75,7 @@ type TProtocol interface {
ReadBinary() (value []byte, err error) ReadBinary() (value []byte, err error)
Skip(fieldType TType) (err error) Skip(fieldType TType) (err error)
Flush() (err error) Flush(ctx context.Context) (err error)
Transport() TTransport Transport() TTransport
} }

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"bytes" "bytes"
"context"
"io/ioutil" "io/ioutil"
"math" "math"
"net" "net"
@ -234,7 +235,7 @@ func ReadWriteBool(t testing.TB, p TProtocol, trans TTransport) {
if err != nil { if err != nil {
t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES) 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() thetype2, thelen2, err := p.ReadListBegin()
if err != nil { if err != nil {
t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteBool", p, trans, err, BOOL_VALUES) 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 { if err != nil {
t.Errorf("%s: %T %T %q Error writing list end: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES) 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 { if err != nil {
t.Errorf("%s: %T %T %q Error flushing list of bytes: %q", "ReadWriteByte", p, trans, err, BYTE_VALUES) 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.WriteI16(v)
} }
p.WriteListEnd() p.WriteListEnd()
p.Flush() p.Flush(context.Background())
thetype2, thelen2, err := p.ReadListBegin() thetype2, thelen2, err := p.ReadListBegin()
if err != nil { if err != nil {
t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI16", p, trans, err, INT16_VALUES) 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.WriteI32(v)
} }
p.WriteListEnd() p.WriteListEnd()
p.Flush() p.Flush(context.Background())
thetype2, thelen2, err := p.ReadListBegin() thetype2, thelen2, err := p.ReadListBegin()
if err != nil { if err != nil {
t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI32", p, trans, err, INT32_VALUES) 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.WriteI64(v)
} }
p.WriteListEnd() p.WriteListEnd()
p.Flush() p.Flush(context.Background())
thetype2, thelen2, err := p.ReadListBegin() thetype2, thelen2, err := p.ReadListBegin()
if err != nil { if err != nil {
t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteI64", p, trans, err, INT64_VALUES) 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.WriteDouble(v)
} }
p.WriteListEnd() p.WriteListEnd()
p.Flush() p.Flush(context.Background())
thetype2, thelen2, err := p.ReadListBegin() thetype2, thelen2, err := p.ReadListBegin()
if err != nil { if err != nil {
t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteDouble", p, trans, err, DOUBLE_VALUES) 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.WriteString(v)
} }
p.WriteListEnd() p.WriteListEnd()
p.Flush() p.Flush(context.Background())
thetype2, thelen2, err := p.ReadListBegin() thetype2, thelen2, err := p.ReadListBegin()
if err != nil { if err != nil {
t.Errorf("%s: %T %T %q Error reading list: %q", "ReadWriteString", p, trans, err, STRING_VALUES) 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) { func ReadWriteBinary(t testing.TB, p TProtocol, trans TTransport) {
v := protocol_bdata v := protocol_bdata
p.WriteBinary(v) p.WriteBinary(v)
p.Flush() p.Flush(context.Background())
value, err := p.ReadBinary() value, err := p.ReadBinary()
if err != nil { if err != nil {
t.Errorf("%s: %T %T Unable to read binary: %s", "ReadWriteBinary", p, trans, err.Error()) t.Errorf("%s: %T %T Unable to read binary: %s", "ReadWriteBinary", p, trans, err.Error())

View File

@ -19,6 +19,10 @@
package thrift package thrift
import (
"context"
)
type TSerializer struct { type TSerializer struct {
Transport *TMemoryBuffer Transport *TMemoryBuffer
Protocol TProtocol Protocol TProtocol
@ -38,35 +42,35 @@ func NewTSerializer() *TSerializer {
protocol} 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() t.Transport.Reset()
if err = msg.Write(t.Protocol); err != nil { if err = msg.Write(t.Protocol); err != nil {
return return
} }
if err = t.Protocol.Flush(); err != nil { if err = t.Protocol.Flush(ctx); err != nil {
return return
} }
if err = t.Transport.Flush(); err != nil { if err = t.Transport.Flush(ctx); err != nil {
return return
} }
return t.Transport.String(), nil 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() t.Transport.Reset()
if err = msg.Write(t.Protocol); err != nil { if err = msg.Write(t.Protocol); err != nil {
return return
} }
if err = t.Protocol.Flush(); err != nil { if err = t.Protocol.Flush(ctx); err != nil {
return return
} }
if err = t.Transport.Flush(); err != nil { if err = t.Transport.Flush(ctx); err != nil {
return return
} }

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"testing" "testing"
@ -88,7 +89,7 @@ func ProtocolTest1(test *testing.T, pf ProtocolFactory) (bool, error) {
m.StringSet = make(map[string]struct{}, 5) m.StringSet = make(map[string]struct{}, 5)
m.E = 2 m.E = 2
s, err := t.WriteString(&m) s, err := t.WriteString(context.Background(), &m)
if err != nil { if err != nil {
return false, errors.New(fmt.Sprintf("Unable to Serialize struct\n\t %s", err)) 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.StringSet = make(map[string]struct{}, 5)
m.E = 2 m.E = 2
s, err := t.WriteString(&m) s, err := t.WriteString(context.Background(), &m)
if err != nil { if err != nil {
return false, errors.New(fmt.Sprintf("Unable to Serialize struct\n\t %s", err)) return false, errors.New(fmt.Sprintf("Unable to Serialize struct\n\t %s", err))

View File

@ -22,6 +22,7 @@ package thrift
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -552,7 +553,7 @@ func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, error) {
return v, p.ParsePostValue() return v, p.ParsePostValue()
} }
func (p *TSimpleJSONProtocol) Flush() (err error) { func (p *TSimpleJSONProtocol) Flush(ctx context.Context) (err error) {
return NewTProtocolException(p.writer.Flush()) return NewTProtocolException(p.writer.Flush())
} }

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -37,7 +38,7 @@ func TestWriteSimpleJSONProtocolBool(t *testing.T) {
if e := p.WriteBool(value); e != nil { if e := p.WriteBool(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -63,7 +64,7 @@ func TestReadSimpleJSONProtocolBool(t *testing.T) {
} else { } else {
trans.Write(JSON_FALSE) trans.Write(JSON_FALSE)
} }
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadBool() v, e := p.ReadBool()
if e != nil { if e != nil {
@ -88,7 +89,7 @@ func TestWriteSimpleJSONProtocolByte(t *testing.T) {
if e := p.WriteByte(value); e != nil { if e := p.WriteByte(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -110,7 +111,7 @@ func TestReadSimpleJSONProtocolByte(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(strconv.Itoa(int(value))) trans.WriteString(strconv.Itoa(int(value)))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadByte() v, e := p.ReadByte()
if e != nil { if e != nil {
@ -135,7 +136,7 @@ func TestWriteSimpleJSONProtocolI16(t *testing.T) {
if e := p.WriteI16(value); e != nil { if e := p.WriteI16(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -157,7 +158,7 @@ func TestReadSimpleJSONProtocolI16(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(strconv.Itoa(int(value))) trans.WriteString(strconv.Itoa(int(value)))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI16() v, e := p.ReadI16()
if e != nil { if e != nil {
@ -182,7 +183,7 @@ func TestWriteSimpleJSONProtocolI32(t *testing.T) {
if e := p.WriteI32(value); e != nil { if e := p.WriteI32(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -204,7 +205,7 @@ func TestReadSimpleJSONProtocolI32(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(strconv.Itoa(int(value))) trans.WriteString(strconv.Itoa(int(value)))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI32() v, e := p.ReadI32()
if e != nil { if e != nil {
@ -228,7 +229,7 @@ func TestReadSimpleJSONProtocolI32Null(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(value) trans.WriteString(value)
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI32() v, e := p.ReadI32()
@ -250,7 +251,7 @@ func TestWriteSimpleJSONProtocolI64(t *testing.T) {
if e := p.WriteI64(value); e != nil { if e := p.WriteI64(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -272,7 +273,7 @@ func TestReadSimpleJSONProtocolI64(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(strconv.FormatInt(value, 10)) trans.WriteString(strconv.FormatInt(value, 10))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI64() v, e := p.ReadI64()
if e != nil { if e != nil {
@ -296,7 +297,7 @@ func TestReadSimpleJSONProtocolI64Null(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(value) trans.WriteString(value)
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadI64() v, e := p.ReadI64()
@ -318,7 +319,7 @@ func TestWriteSimpleJSONProtocolDouble(t *testing.T) {
if e := p.WriteDouble(value); e != nil { if e := p.WriteDouble(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -355,7 +356,7 @@ func TestReadSimpleJSONProtocolDouble(t *testing.T) {
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
n := NewNumericFromDouble(value) n := NewNumericFromDouble(value)
trans.WriteString(n.String()) trans.WriteString(n.String())
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadDouble() v, e := p.ReadDouble()
if e != nil { if e != nil {
@ -394,7 +395,7 @@ func TestWriteSimpleJSONProtocolString(t *testing.T) {
if e := p.WriteString(value); e != nil { if e := p.WriteString(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -416,7 +417,7 @@ func TestReadSimpleJSONProtocolString(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(jsonQuote(value)) trans.WriteString(jsonQuote(value))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadString() v, e := p.ReadString()
if e != nil { if e != nil {
@ -440,7 +441,7 @@ func TestReadSimpleJSONProtocolStringNull(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(value) trans.WriteString(value)
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadString() v, e := p.ReadString()
if e != nil { if e != nil {
@ -464,7 +465,7 @@ func TestWriteSimpleJSONProtocolBinary(t *testing.T) {
if e := p.WriteBinary(value); e != nil { if e := p.WriteBinary(value); e != nil {
t.Fatalf("Unable to write %s value %v due to error: %s", thetype, value, e.Error()) 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()) t.Fatalf("Unable to write %s value %v due to error flushing: %s", thetype, value, e.Error())
} }
s := trans.String() s := trans.String()
@ -487,7 +488,7 @@ func TestReadSimpleJSONProtocolBinary(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(jsonQuote(b64String)) trans.WriteString(jsonQuote(b64String))
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
v, e := p.ReadBinary() v, e := p.ReadBinary()
if e != nil { if e != nil {
@ -516,7 +517,7 @@ func TestReadSimpleJSONProtocolBinaryNull(t *testing.T) {
trans := NewTMemoryBuffer() trans := NewTMemoryBuffer()
p := NewTSimpleJSONProtocol(trans) p := NewTSimpleJSONProtocol(trans)
trans.WriteString(value) trans.WriteString(value)
trans.Flush() trans.Flush(context.Background())
s := trans.String() s := trans.String()
b, e := p.ReadBinary() b, e := p.ReadBinary()
v := string(b) v := string(b)
@ -542,7 +543,7 @@ func TestWriteSimpleJSONProtocolList(t *testing.T) {
} }
} }
p.WriteListEnd() 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()) t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
} }
str := trans.String() str := trans.String()
@ -596,7 +597,7 @@ func TestWriteSimpleJSONProtocolSet(t *testing.T) {
} }
} }
p.WriteSetEnd() 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()) t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
} }
str := trans.String() str := trans.String()
@ -653,7 +654,7 @@ func TestWriteSimpleJSONProtocolMap(t *testing.T) {
} }
} }
p.WriteMapEnd() 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()) t.Fatalf("Unable to write %s due to error flushing: %s", thetype, e.Error())
} }
str := trans.String() str := trans.String()

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"net" "net"
"time" "time"
) )
@ -148,7 +149,7 @@ func (p *TSocket) Write(buf []byte) (int, error) {
return p.conn.Write(buf) return p.conn.Write(buf)
} }
func (p *TSocket) Flush() error { func (p *TSocket) Flush(ctx context.Context) error {
return nil return nil
} }

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"crypto/tls" "crypto/tls"
"net" "net"
"time" "time"
@ -158,7 +159,7 @@ func (p *TSSLSocket) Write(buf []byte) (int, error) {
return p.conn.Write(buf) return p.conn.Write(buf)
} }
func (p *TSSLSocket) Flush() error { func (p *TSSLSocket) Flush(ctx context.Context) error {
return nil return nil
} }

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"errors" "errors"
"io" "io"
) )
@ -30,6 +31,10 @@ type Flusher interface {
Flush() (err error) Flush() (err error)
} }
type ContextFlusher interface {
Flush(ctx context.Context) (err error)
}
type ReadSizeProvider interface { type ReadSizeProvider interface {
RemainingBytes() (num_bytes uint64) RemainingBytes() (num_bytes uint64)
} }
@ -37,7 +42,7 @@ type ReadSizeProvider interface {
// Encapsulates the I/O layer // Encapsulates the I/O layer
type TTransport interface { type TTransport interface {
io.ReadWriteCloser io.ReadWriteCloser
Flusher ContextFlusher
ReadSizeProvider ReadSizeProvider
// Opens the transport for communication // Opens the transport for communication
@ -60,6 +65,6 @@ type TRichTransport interface {
io.ByteReader io.ByteReader
io.ByteWriter io.ByteWriter
stringWriter stringWriter
Flusher ContextFlusher
ReadSizeProvider ReadSizeProvider
} }

View File

@ -20,6 +20,7 @@
package thrift package thrift
import ( import (
"context"
"io" "io"
"net" "net"
"strconv" "strconv"
@ -54,7 +55,7 @@ func TransportTest(t *testing.T, writeTrans TTransport, readTrans TTransport) {
if err != nil { if err != nil {
t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err) 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 { if err != nil {
t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err) 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 { if err != nil {
t.Fatalf("Transport %T cannot write binary data 2 of length %d: %s", writeTrans, len(transport_bdata), err) 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 { if err != nil {
t.Fatalf("Transport %T cannot flush write binary data 2: %s", writeTrans, err) 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 { if err != nil {
t.Fatalf("Transport %T cannot write binary data of length %d: %s", writeTrans, len(transport_bdata), err) 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 { if err != nil {
t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err) t.Fatalf("Transport %T cannot flush write of binary data: %s", writeTrans, err)
} }

View File

@ -21,6 +21,7 @@ package thrift
import ( import (
"compress/zlib" "compress/zlib"
"context"
"io" "io"
"log" "log"
) )
@ -91,11 +92,11 @@ func (z *TZlibTransport) Close() error {
} }
// Flush flushes the writer and its underlying transport. // 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 { if err := z.writer.Flush(); err != nil {
return err return err
} }
return z.transport.Flush() return z.transport.Flush(ctx)
} }
// IsOpen returns true if the transport is open // IsOpen returns true if the transport is open

View File

@ -18,9 +18,6 @@
# #
BUILT_SOURCES = gopath BUILT_SOURCES = gopath
if GOVERSION_LT_17
COMPILER_EXTRAFLAG=",legacy_context"
endif
THRIFTCMD = $(THRIFT) -out src/gen --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG) THRIFTCMD = $(THRIFT) -out src/gen --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG)
THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift
@ -37,7 +34,6 @@ gopath: $(THRIFT) ThriftTest.thrift
mkdir -p src/gen mkdir -p src/gen
$(THRIFTCMD) ThriftTest.thrift $(THRIFTCMD) ThriftTest.thrift
$(THRIFTCMD) ../StressTest.thrift $(THRIFTCMD) ../StressTest.thrift
GOPATH=`pwd` $(GO) get golang.org/x/net/context
GOPATH=`pwd` $(GO) get github.com/golang/mock/gomock || true 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 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 GOPATH=`pwd` $(GO) get github.com/golang/mock/gomock

View File

@ -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
}

View File

@ -20,6 +20,7 @@
package main package main
import ( import (
"context"
"flag" "flag"
"fmt" "fmt"
"gen/stress" "gen/stress"
@ -216,3 +217,38 @@ func client(protocolFactory thrift.TProtocolFactory) {
done.Done() 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
}

View File

@ -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
}

View File

@ -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()

View File

@ -21,6 +21,7 @@ package main
import ( import (
"common" "common"
"context"
"flag" "flag"
"gen/thrifttest" "gen/thrifttest"
t "log" t "log"
@ -60,6 +61,7 @@ var xxs = &thrifttest.Xtruct{
} }
var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "Xception"} var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "Xception"}
var defaultCtx = context.Background()
func callEverything(client *thrifttest.ThriftTestClient) { func callEverything(client *thrifttest.ThriftTestClient) {
var err error var err error

View File

@ -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()

View File

@ -20,6 +20,7 @@
package common package common
import ( import (
"context"
"errors" "errors"
"gen/thrifttest" "gen/thrifttest"
"reflect" "reflect"
@ -95,6 +96,7 @@ var xxs = &thrifttest.Xtruct{
} }
var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "some"} var xcept = &thrifttest.Xception{ErrorCode: 1001, Message: "some"}
var defaultCtx = context.Background()
func callEverythingWithMock(t *testing.T, client *thrifttest.ThriftTestClient, handler *MockThriftTest) { func callEverythingWithMock(t *testing.T, client *thrifttest.ThriftTestClient, handler *MockThriftTest) {
gomock.InOrder( gomock.InOrder(

View File

@ -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)
}
}

View File

@ -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()

View File

@ -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()

View File

@ -1,5 +1,3 @@
// +build !go1.7
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file
@ -22,13 +20,12 @@
package common package common
import ( import (
"context"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"encoding/hex"
. "gen/thrifttest" . "gen/thrifttest"
"time" "time"
"golang.org/x/net/context"
) )
var PrintingHandler = &printingHandler{} 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) { func (p *printingHandler) TestInsanity(ctx context.Context, argument *Insanity) (r map[UserId]map[Numberz]*Insanity, err error) {
fmt.Printf("testInsanity()\n") fmt.Printf("testInsanity()\n")
r = make(map[UserId]map[Numberz]*Insanity) r = make(map[UserId]map[Numberz]*Insanity)
r[1] = map[Numberz]*Insanity { r[1] = map[Numberz]*Insanity{
2: argument, 2: argument,
3: argument, 3: argument,
} }
r[2] = map[Numberz]*Insanity { r[2] = map[Numberz]*Insanity{
6: NewInsanity(), 6: NewInsanity(),
} }
return return

View File

@ -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<i32,i32> thing - the map<i32,i32> to print
// @return map<i32,i32> - returns the map<i32,i32> '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<string,string> thing - the map<string,string> to print
// @return map<string,string> - returns the map<string,string> '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<i32> thing - the set<i32> to print
// @return set<i32> - returns the set<i32> '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<i32> thing - the list<i32> to print
// @return list<i32> - returns the list<i32> '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<i32,map<i32,i32>> - 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 => <empty Insanity struct>, },
// }
// @return map<UserId, map<Numberz,Insanity>> - 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<i16, string> 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
}

View File

@ -17,10 +17,6 @@
# under the License. # 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 gen-go/tutorial/calculator.go gen-go/shared/shared_service.go: $(top_srcdir)/tutorial/tutorial.thrift
$(THRIFT) --gen go$(COMPILER_EXTRAFLAG) -r $< $(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 ln -sf $(realpath $(top_srcdir)/lib/go/thrift) src/git.apache.org/thrift.git/lib/go/thrift
thirdparty-dep: 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 tutorialserver: all
GOPATH=`pwd` $(GO) run src/*.go -server=true GOPATH=`pwd` $(GO) run src/*.go -server=true
@ -61,9 +54,6 @@ EXTRA_DIST = \
src/handler.go \ src/handler.go \
src/server.go \ src/server.go \
src/main.go \ src/main.go \
src/go17.go \
src/handler_go17.go \
src/pre_go17.go \
server.crt \ server.crt \
server.key server.key

View File

@ -20,6 +20,7 @@ package main
*/ */
import ( import (
"context"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"tutorial" "tutorial"
@ -27,6 +28,8 @@ import (
"git.apache.org/thrift.git/lib/go/thrift" "git.apache.org/thrift.git/lib/go/thrift"
) )
var defaultCtx = context.Background()
func handleClient(client *tutorial.CalculatorClient) (err error) { func handleClient(client *tutorial.CalculatorClient) (err error) {
client.Ping(defaultCtx) client.Ping(defaultCtx)
fmt.Println("ping()") fmt.Println("ping()")

View File

@ -1,5 +1,3 @@
// +build !go1.7
package main package main
/* /*
@ -22,12 +20,11 @@ package main
*/ */
import ( import (
"context"
"fmt" "fmt"
"shared" "shared"
"strconv" "strconv"
"tutorial" "tutorial"
"golang.org/x/net/context"
) )
type CalculatorHandler struct { type CalculatorHandler struct {

View File

@ -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
}

View File

@ -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()