Update zipkin to the newer version (#1205)

* Update zipkin to the newer version

Also update thrift to use head commit

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

* Update vendor directory.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2017-11-08 08:21:11 -08:00 committed by Miek Gieben
parent 3527be6c00
commit f6caa48b94
150 changed files with 4899 additions and 2890 deletions

26
Gopkg.lock generated
View file

@ -22,8 +22,7 @@
[[projects]] [[projects]]
name = "github.com/apache/thrift" name = "github.com/apache/thrift"
packages = ["lib/go/thrift"] packages = ["lib/go/thrift"]
revision = "b2a4d4ae21c789b689dd162deb819665567f481c" revision = "4f77ab8e296d64c57e6ea1c6e3f0f152bc7d6a3a"
version = "0.10.0"
[[projects]] [[projects]]
name = "github.com/asaskevich/govalidator" name = "github.com/asaskevich/govalidator"
@ -149,7 +148,7 @@
branch = "master" branch = "master"
name = "github.com/go-openapi/spec" name = "github.com/go-openapi/spec"
packages = ["."] packages = ["."]
revision = "84b5bee7bcb76f3d17bcbaf421bac44bd5709ca6" revision = "a4fa9574c7aa73b2fc54e251eb9524d0482bb592"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -197,7 +196,7 @@
branch = "master" branch = "master"
name = "github.com/grpc-ecosystem/grpc-opentracing" name = "github.com/grpc-ecosystem/grpc-opentracing"
packages = ["go/otgrpc"] packages = ["go/otgrpc"]
revision = "a570af39704b9f3d4bb530d83192a99ea6337d5a" revision = "01f8541d537215b2867e2745a1eb85c58c7c6b81"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -233,7 +232,7 @@
branch = "master" branch = "master"
name = "github.com/mailru/easyjson" name = "github.com/mailru/easyjson"
packages = ["buffer","jlexer","jwriter"] packages = ["buffer","jlexer","jwriter"]
revision = "4d347d79dea0067c945f374f990601decb08abb5" revision = "5f62e4f3afa2f576dc86531b7df4d966b19ef8f8"
[[projects]] [[projects]]
name = "github.com/matttproud/golang_protobuf_extensions" name = "github.com/matttproud/golang_protobuf_extensions"
@ -247,6 +246,12 @@
packages = ["."] packages = ["."]
revision = "06020f85339e21b2478f756a78e295255ffa4d6a" revision = "06020f85339e21b2478f756a78e295255ffa4d6a"
[[projects]]
branch = "master"
name = "github.com/opentracing-contrib/go-observer"
packages = ["."]
revision = "a52f2342449246d5bcc273e65cbdcfa5f7d6c63c"
[[projects]] [[projects]]
name = "github.com/opentracing/opentracing-go" name = "github.com/opentracing/opentracing-go"
packages = [".","ext","log"] packages = [".","ext","log"]
@ -255,9 +260,8 @@
[[projects]] [[projects]]
name = "github.com/openzipkin/zipkin-go-opentracing" name = "github.com/openzipkin/zipkin-go-opentracing"
packages = [".","_thrift/gen-go/scribe","_thrift/gen-go/zipkincore","flag","types","wire"] packages = [".","flag","thrift/gen-go/scribe","thrift/gen-go/zipkincore","types","wire"]
revision = "d88c90182f3fb514be54a1c7adc11a04d41c7da9" revision = "45e90b00710a4c34a1a7d8a78d90f9b010b0bd4d"
version = "v0.2.4"
[[projects]] [[projects]]
name = "github.com/pierrec/lz4" name = "github.com/pierrec/lz4"
@ -316,13 +320,13 @@
branch = "master" branch = "master"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
packages = ["ssh/terminal"] packages = ["ssh/terminal"]
revision = "bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8" revision = "6a293f2d4b14b8e6d3f0539e383f6d0d30fce3fd"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/sys" name = "golang.org/x/sys"
packages = ["unix","windows"] packages = ["unix","windows"]
revision = "4fe5d7925040acd225bf9c7cee65e82d07f06bff" revision = "75813c647272dd855bda156405bf844a5414f5bf"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -374,6 +378,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "9e6593b26c8f9a3841e988e46627fa440748742be455c2523b66b01501796ca4" inputs-digest = "c7279ef091bb11a42d1421f51e53d761113ea23d9e9b993823605883da0f80ff"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View file

@ -15,7 +15,10 @@ ignored = [
[[constraint]] [[constraint]]
name = "github.com/openzipkin/zipkin-go-opentracing" name = "github.com/openzipkin/zipkin-go-opentracing"
version = "v0.2.3" revision = "45e90b00710a4c34a1a7d8a78d90f9b010b0bd4d"
[[override]]
name = "github.com/apache/thrift"
revision = "4f77ab8e296d64c57e6ea1c6e3f0f152bc7d6a3a"
[[override]] [[override]]
name = "github.com/ugorji/go" name = "github.com/ugorji/go"
@ -23,8 +26,8 @@ ignored = [
# client-go 4.0.0 uses apimachinery 1fd2e63a9a370677308a42f24fd40c86438afddf (see Godep.json) # client-go 4.0.0 uses apimachinery 1fd2e63a9a370677308a42f24fd40c86438afddf (see Godep.json)
[[constraint]] [[constraint]]
name = "k8s.io/client-go" name = "k8s.io/client-go"
version = "v4.0.0" version = "v4.0.0"
[[override]] [[override]]
name = "k8s.io/apimachinery" name = "k8s.io/apimachinery"
revision = "1fd2e63a9a370677308a42f24fd40c86438afddf" revision = "1fd2e63a9a370677308a42f24fd40c86438afddf"

View file

@ -21,6 +21,7 @@
*.swp *.swp
*.hi *.hi
*~ *~
tags
.*project .*project
junit*.properties junit*.properties
@ -36,6 +37,8 @@ node_modules
compile compile
test-driver test-driver
erl_crash.dump erl_crash.dump
package-lock.json
project.lock.json
.sonar .sonar
.DS_Store .DS_Store
@ -101,6 +104,7 @@ erl_crash.dump
/lib/cpp/src/thrift/stamp-h2 /lib/cpp/src/thrift/stamp-h2
/lib/cpp/test/Benchmark /lib/cpp/test/Benchmark
/lib/cpp/test/AllProtocolsTest /lib/cpp/test/AllProtocolsTest
/lib/cpp/test/AnnotationTest
/lib/cpp/test/DebugProtoTest /lib/cpp/test/DebugProtoTest
/lib/cpp/test/DenseProtoTest /lib/cpp/test/DenseProtoTest
/lib/cpp/test/EnumTest /lib/cpp/test/EnumTest
@ -114,6 +118,7 @@ erl_crash.dump
/lib/cpp/test/TFileTransportTest /lib/cpp/test/TFileTransportTest
/lib/cpp/test/TInterruptTest /lib/cpp/test/TInterruptTest
/lib/cpp/test/TNonblockingServerTest /lib/cpp/test/TNonblockingServerTest
/lib/cpp/test/TNonblockingSSLServerTest
/lib/cpp/test/TPipedTransportTest /lib/cpp/test/TPipedTransportTest
/lib/cpp/test/TServerIntegrationTest /lib/cpp/test/TServerIntegrationTest
/lib/cpp/test/TSocketInterruptTest /lib/cpp/test/TSocketInterruptTest
@ -149,6 +154,7 @@ erl_crash.dump
/lib/c_glib/test/testframedtransport /lib/c_glib/test/testframedtransport
/lib/c_glib/test/testmemorybuffer /lib/c_glib/test/testmemorybuffer
/lib/c_glib/test/testoptionalrequired /lib/c_glib/test/testoptionalrequired
/lib/c_glib/test/testtransportsslsocket
/lib/c_glib/test/testsimpleserver /lib/c_glib/test/testsimpleserver
/lib/c_glib/test/teststruct /lib/c_glib/test/teststruct
/lib/c_glib/test/testthrifttest /lib/c_glib/test/testthrifttest
@ -204,17 +210,26 @@ erl_crash.dump
/lib/delphi/test/typeregistry/*.identcache /lib/delphi/test/typeregistry/*.identcache
/lib/delphi/test/typeregistry/*.local /lib/delphi/test/typeregistry/*.local
/lib/delphi/test/typeregistry/*.dcu /lib/delphi/test/typeregistry/*.dcu
/lib/erl/.generated
/lib/erl/.eunit /lib/erl/.eunit
/lib/erl/ebin /lib/erl/.generated
/lib/erl/.rebar/
/lib/erl/deps/ /lib/erl/deps/
/lib/erl/ebin
/lib/erl/src/thrift.app.src /lib/erl/src/thrift.app.src
/lib/erl/test/*.hrl
/lib/erl/test/*.beam /lib/erl/test/*.beam
/lib/erl/test/*.hrl
/lib/erl/test/Thrift_omit_without.thrift
/lib/haxe/test/bin /lib/haxe/test/bin
/lib/hs/dist /lib/hs/dist
/lib/java/build /lib/java/build
/lib/js/dist
/lib/js/doc
/lib/js/package-lock.json
/lib/js/test/build /lib/js/test/build
/lib/netcore/**/.vs
/lib/netcore/**/bin
/lib/netcore/**/obj
/lib/netcore/**/gen-*
/lib/nodejs/coverage /lib/nodejs/coverage
/lib/nodejs/node_modules/ /lib/nodejs/node_modules/
/lib/perl/MANIFEST /lib/perl/MANIFEST
@ -254,8 +269,22 @@ erl_crash.dump
/lib/php/test/packages/ /lib/php/test/packages/
/lib/py/dist/ /lib/py/dist/
/lib/erl/logs/ /lib/erl/logs/
/lib/go/pkg
/lib/go/src
/lib/go/test/gopath/ /lib/go/test/gopath/
/lib/go/test/ThriftTest.thrift /lib/go/test/ThriftTest.thrift
/lib/rs/target/
/lib/rs/Cargo.lock
/lib/rs/test/Cargo.lock
/lib/rs/test/target/
/lib/rs/test/bin/
/lib/rs/test/src/base_one.rs
/lib/rs/test/src/base_two.rs
/lib/rs/test/src/midlayer.rs
/lib/rs/test/src/recursive.rs
/lib/rs/test/src/ultimate.rs
/lib/rs/*.iml
/lib/rs/**/*.iml
/libtool /libtool
/ltmain.sh /ltmain.sh
/missing /missing
@ -276,20 +305,36 @@ erl_crash.dump
/test/log/ /test/log/
/test/test.log /test/test.log
/test/erl/.generated /test/erl/.generated
/test/erl/.rebar
/test/erl/ebin /test/erl/ebin
/test/go/bin/ /test/go/bin/
/test/go/ThriftTest.thrift /test/go/ThriftTest.thrift
/test/go/gopath /test/go/gopath
/test/go/pkg/ /test/go/pkg/
/test/go/src/code.google.com/ /test/go/src/code.google.com/
/test/go/src/common/mock_handler.go
/test/go/src/github.com/golang/ /test/go/src/github.com/golang/
/test/go/src/golang.org/
/test/go/src/gen/ /test/go/src/gen/
/test/go/src/thrift /test/go/src/thrift
/test/haxe/bin /test/haxe/bin
/test/hs/TestClient /test/hs/TestClient
/test/hs/TestServer /test/hs/TestServer
/test/php/php_ext_dir/
/test/py.twisted/_trial_temp/ /test/py.twisted/_trial_temp/
/test/rb/Gemfile.lock /test/rb/Gemfile.lock
/test/netcore/**/.vs
/test/netcore/**/bin
/test/netcore/**/obj
/test/netcore/**/gen-*
/test/netcore/Thrift
/test/php/php_ext_dir/
/test/rs/Cargo.lock
/test/rs/src/thrift_test.rs
/test/rs/bin/
/test/rs/target/
/test/rs/*.iml
/test/rs/**/*.iml
/tutorial/cpp/TutorialClient /tutorial/cpp/TutorialClient
/tutorial/cpp/TutorialServer /tutorial/cpp/TutorialServer
/tutorial/c_glib/tutorial_client /tutorial/c_glib/tutorial_client
@ -314,13 +359,26 @@ erl_crash.dump
/tutorial/delphi/DelphiClient/*.identcache /tutorial/delphi/DelphiClient/*.identcache
/tutorial/delphi/DelphiServer/*.identcache /tutorial/delphi/DelphiServer/*.identcache
/tutorial/delphi/DelphiServer/*.local /tutorial/delphi/DelphiServer/*.local
/tutorial/go/gopath
/tutorial/go/go-tutorial /tutorial/go/go-tutorial
/tutorial/go/calculator-remote /tutorial/go/calculator-remote
/tutorial/go/src/shared /tutorial/go/src/shared
/tutorial/go/src/tutorial /tutorial/go/src/tutorial
/tutorial/go/src/git.apache.org /tutorial/go/src/git.apache.org
/tutorial/go/src/golang.org
/tutorial/haxe/bin /tutorial/haxe/bin
/tutorial/hs/dist/ /tutorial/hs/dist/
/tutorial/java/build/ /tutorial/java/build/
/tutorial/js/build/ /tutorial/js/build/
/tutorial/netcore/**/.vs
/tutorial/netcore/**/bin
/tutorial/netcore/**/obj
/tutorial/netcore/**/gen-*
/tutorial/netcore/Thrift
/tutorial/rs/*.iml
/tutorial/rs/src/shared.rs
/tutorial/rs/src/tutorial.rs
/tutorial/rs/bin
/tutorial/rs/target
/tutorial/rs/Cargo.lock
/ylwrap /ylwrap

7
vendor/github.com/apache/thrift/.rustfmt.toml generated vendored Normal file
View file

@ -0,0 +1,7 @@
max_width = 100
fn_args_layout = "Block"
array_layout = "Block"
where_style = "Rfc"
generics_indent = "Block"
fn_call_style = "Block"
reorder_imported_names = true

View file

@ -19,181 +19,178 @@
# build Apache Thrift on Travis CI - https://travis-ci.org/ # build Apache Thrift on Travis CI - https://travis-ci.org/
#
# Docker Integration
# see: build/docker/README.md
#
sudo: required sudo: required
dist: trusty dist: trusty
language: cpp
services: services:
- docker - docker
install: install:
- (travis_wait ./build/docker/check_unmodified.sh $DISTRO && touch .unmodified) || true - if [[ `uname` == "Linux" ]]; then build/docker/refresh.sh; fi
- if [ ! -f .unmodified ]; then travis_retry travis_wait docker build -q -t thrift-build:$DISTRO build/docker/$DISTRO; fi
script: stages:
- docker run --net=host -e BUILD_LIBS="$BUILD_LIBS" $BUILD_ENV -v $(pwd):/thrift/src -it thrift-build:$DISTRO build/docker/scripts/$SCRIPT $BUILD_ARG # - osx # up front for now (for testing)
- docker # docker images
- thrift # thrift build jobs
env: env:
global: global:
- TEST_NAME=""
- SCRIPT="cmake.sh" - SCRIPT="cmake.sh"
- BUILD_ARG="" - BUILD_ARG=""
- BUILD_ENV="-e CC=clang -e CXX=clang++" - BUILD_ENV="-e CC=clang -e CXX=clang++"
- DISTRO=ubuntu - DISTRO=ubuntu-xenial
- BUILD_LIBS="CPP C_GLIB HASKELL JAVA PYTHON TESTING TUTORIALS" # only meaningful for CMake builds - BUILD_LIBS="CPP C_GLIB HASKELL JAVA PYTHON TESTING TUTORIALS" # only meaningful for CMake builds
- TRAVIS_BUILD_STAGE=test
# DOCKER_REPO (this works for all builds as a source for docker images - you can override for fork builds in your Travis settings)
- DOCKER_REPO="thrift/thrift-build"
# DOCKER_USER (provide in your Travis settings if you want to build and update docker images once, instead of on every job)
# DOCKER_PASS (same)
matrix: jobs:
- TEST_NAME="Cross Language Tests (Binary and Header Protocols)"
SCRIPT="cross-test.sh"
BUILD_ARG="-'(binary|header)'"
BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
- TEST_NAME="Cross Language Tests (Debian) (Binary and Header Protocols)"
SCRIPT="cross-test.sh"
BUILD_ARG="-'(binary|header)'"
BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
DISTRO=debian
- TEST_NAME="Cross Language Tests (Compact and JSON Protocols)"
SCRIPT="cross-test.sh"
BUILD_ARG="-'(compact|json)'"
BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
- TEST_NAME="Cross Language Tests (Debian) (Compact and JSON Protocols)"
SCRIPT="cross-test.sh"
BUILD_ARG="-'(compact|json)'"
BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
DISTRO=debian
# TODO: Remove them once migrated to CMake
# Autotools builds
- TEST_NAME="C C++ C# D Erlang Haxe Go (automake)"
SCRIPT="autotools.sh"
BUILD_ARG="--without-dart --without-haskell --without-java --without-lua --without-nodejs --without-perl --without-php --without-php_extension --without-python --without-ruby"
- TEST_NAME="C C++ - GCC (automake)"
SCRIPT="autotools.sh"
BUILD_ARG="--without-csharp --without-java --without-erlang --without-nodejs --without-lua --without-python --without-perl --without-php --without-php_extension --without-dart --without-ruby --without-haskell --without-go --without-haxe --without-d"
BUILD_ENV="-e CC=gcc -e CXX=g++"
- TEST_NAME="Java Lua PHP Ruby Dart (automake)"
SCRIPT="autotools.sh"
BUILD_ARG="--without-cpp --without-haskell --without-c_glib --without-csharp --without-d --without-erlang --without-go --without-haxe --without-nodejs --without-python --without-perl"
# These are flaky (due to cabal and npm network/server failures) and also have lengthy output
- TEST_NAME="Haskell Node.js Python Perl (automake)"
SCRIPT="autotools.sh"
BUILD_ARG="--without-cpp --without-c_glib --without-csharp --without-d --without-dart --without-erlang --without-go --without-haxe --without-java --without-lua --without-php --without-php_extension --without-ruby"
# CMake build
- TEST_NAME="All"
- TEST_NAME="All (Debian)"
DISTRO=debian
- TEST_NAME="C C++ - GCC"
BUILD_LIBS="CPP C_GLIB TESTING TUTORIALS"
BUILD_ARG="-DWITH_PYTHON=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
BUILD_ENV="-e CC=gcc -e CXX=g++"
- TEST_NAME="C++ (Boost Thread)"
BUILD_LIBS="CPP TESTING TUTORIALS"
BUILD_ARG="-DWITH_BOOSTTHREADS=ON -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
- TEST_NAME="C++ (Boost Thread - GCC)"
BUILD_LIBS="CPP TESTING TUTORIALS"
BUILD_ARG="-DWITH_BOOSTTHREADS=ON -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
BUILD_ENV="-e CC=gcc -e CXX=g++"
- TEST_NAME="C++ (Std Thread)"
BUILD_LIBS="CPP TESTING TUTORIALS"
BUILD_ARG="-DWITH_STDTHREADS=ON -DCMAKE_CXX_FLAGS='-std=c++11' -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
- TEST_NAME="C++ (Std Thread - GCC)"
BUILD_LIBS="CPP TESTING TUTORIALS"
BUILD_ARG="-DWITH_STDTHREADS=ON -DCMAKE_CXX_FLAGS='-std=c++11' -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
BUILD_ENV="-e CC=gcc -e CXX=g++"
- TEST_NAME="Compiler (mingw)"
BUILD_LIBS=""
BUILD_ARG="-DCMAKE_TOOLCHAIN_FILE=../build/cmake/mingw32-toolchain.cmake -DBUILD_COMPILER=ON -DBUILD_LIBRARIES=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF"
BUILD_ENV=""
- TEST_NAME="All - GCC (CentOS)"
BUILD_ENV="-e CC=gcc -e CXX=g++"
DISTRO=centos
- TEST_NAME="C C++ - Clang (CentOS)"
BUILD_LIBS="CPP C_GLIB TESTING TUTORIALS"
BUILD_ARG="-DWITH_PYTHON=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
DISTRO=centos
- TEST_NAME="Python 2.6 (CentOS 6)"
BUILD_LIBS="PYTHON TESTING TUTORIALS"
BUILD_ARG="-DWITH_PYTHON=ON -DWITH_CPP=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
BUILD_ENV="-e CC=gcc -e CXX=g++"
DISTRO=centos6
# Distribution
- TEST_NAME="make dist"
SCRIPT="make-dist.sh"
BUILD_ENV="-e CC=gcc -e CXX=g++"
- TEST_NAME="Debian Packages"
SCRIPT="dpkg.sh"
BUILD_ENV="-e CC=gcc -e CXX=g++"
- TEST_NAME="make dist (Debian)"
SCRIPT="make-dist.sh"
BUILD_ENV="-e CC=gcc -e CXX=g++"
DISTRO=debian
- TEST_NAME="Debian Packages (Debian)"
SCRIPT="dpkg.sh"
BUILD_ENV="-e CC=gcc -e CXX=g++"
DISTRO=debian
matrix:
include: include:
# ------------------------- phase: osx --------------------------
# - stage: osx
# os: osx
# osx_image: xcode9
# script: build/docker/scripts/autotools.sh
# ========================= stage: docker =========================
- stage: docker
script: true
env:
- JOB="Docker Build ubuntu-trusty 14.04"
- DISTRO=ubuntu-trusty
- TRAVIS_BUILD_STAGE=docker
- script: true
env:
- JOB="Docker Build ubuntu-xenial 16.04"
- DISTRO=ubuntu-xenial
- TRAVIS_BUILD_STAGE=docker
- script: true
env:
- JOB="Docker Build ubuntu-artful 17.10"
- DISTRO=ubuntu-artful
- TRAVIS_BUILD_STAGE=docker
# ========================= stage: thrift =======================
# ------------------------- phase: cross ------------------------
# apache/thrift official PR builds can exceed 50 minutes per job so combine all cross tests
- stage: thrift
script: build/docker/run.sh
if: repo = apache/thrift
env:
- JOB="Cross Language Tests"
- SCRIPT="cross-test.sh"
- BUILD_ARG=""
- BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
# fork based PR builds cannot exceed 50 minutes per job
- stage: thrift
script: build/docker/run.sh
if: repo != apache/thrift
env:
- JOB="Cross Language Tests (Binary Protocol)"
- SCRIPT="cross-test.sh"
- BUILD_ARG="-'(binary)'"
- BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
- stage: thrift
script: build/docker/run.sh
if: repo != apache/thrift
env:
- JOB="Cross Language Tests (Header, JSON Protocols)"
- SCRIPT="cross-test.sh"
- BUILD_ARG="-'(header|json)'"
- BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
- stage: thrift
script: build/docker/run.sh
if: repo != apache/thrift
env:
- JOB="Cross Language Tests (Compact and Multiplexed Protocols)"
- SCRIPT="cross-test.sh"
- BUILD_ARG="-'(compact|multiplexed)'"
- BUILD_ENV="-e CC=clang -e CXX=clang++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
# ------------------------- phase: sca --------------------------
# QA jobs for code analytics and metrics # QA jobs for code analytics and metrics
# - stage: thrift
# C/C++ static code analysis with cppcheck script: build/docker/run.sh
# add --error-exitcode=1 to --enable=all as soon as everything is fixed env:
# - JOB="Static Code Analysis"
# Python code style check with flake8 - SCRIPT="sca.sh"
# - DISTRO=ubuntu-artful
# search for TODO etc within source tree
# some statistics about the code base # C and C++ undefined behavior.
# some info about the build machine # A binary crashes if undefined behavior occurs and produces a stack trace.
- env: TEST_NAME="cppcheck, flake8, TODO FIXME HACK, LoC and system info" # python is disabled, see: THRIFT-4360
install: - script: build/docker/run.sh
- travis_retry sudo apt-get update env:
- travis_retry sudo apt-get install -ym cppcheck sloccount python-flake8 - JOB="UBSan"
script: - SCRIPT="ubsan.sh"
# Compiler cppcheck (All) - DISTRO=ubuntu-artful
- cppcheck --force --quiet --inline-suppr --enable=all -j2 compiler/cpp/src - BUILD_ARG="--without-python --without-py3"
# C++ cppcheck (All)
- cppcheck --force --quiet --inline-suppr --enable=all -j2 lib/cpp/src lib/cpp/test test/cpp tutorial/cpp # ------------------------- phase: cmake ------------------------
# C Glib cppcheck (All) - script: build/docker/run.sh
- cppcheck --force --quiet --inline-suppr --enable=all -j2 lib/c_glib/src lib/c_glib/test test/c_glib/src tutorial/c_glib env:
# Silent error checks - JOB="CMake (Ubuntu Xenial)"
- cppcheck --force --quiet --inline-suppr --error-exitcode=1 -j2 compiler/cpp/src
- cppcheck --force --quiet --inline-suppr --error-exitcode=1 -j2 lib/cpp/src lib/cpp/test test/cpp tutorial/cpp # C++ specific options: compiler plug-in, threading model
- cppcheck --force --quiet --inline-suppr --error-exitcode=1 -j2 lib/c_glib/src lib/c_glib/test test/c_glib/src tutorial/c_glib - script: build/docker/run.sh
# Python code style env:
- flake8 --ignore=E501 lib/py - JOB="C++98 (Boost Thread)"
- flake8 tutorial/py - SCRIPT="cmake.sh"
- flake8 --ignore=E501 test/py - BUILD_LIBS="CPP TESTING TUTORIALS"
- flake8 test/py.twisted - BUILD_ARG="-DCMAKE_CXX_STANDARD=98 -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_CXX_EXTENSIONS=OFF --DWITH_BOOSTTHREADS=ON -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
- flake8 test/py.tornado - BUILD_ENV=""
- flake8 --ignore=E501 test/test.py
- flake8 --ignore=E501 test/crossrunner - script: build/docker/run.sh
- flake8 test/features env:
# TODO etc - JOB="C++ (Std Thread) and Plugin"
- grep -r TODO * - SCRIPT="cmake.sh"
- grep -r FIXME * - BUILD_LIBS="CPP TESTING TUTORIALS"
- grep -r HACK * - BUILD_ARG="-DWITH_PLUGIN=ON -DWITH_STDTHREADS=ON -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
# LoC - BUILD_ENV="-e CC=clang -e CXX=clang++"
- sloccount .
# System Info # ------------------------- phase: autotools --------------------
- dpkg -l # TODO: Remove them once migrated to CMake
- uname -a - script: build/docker/run.sh
env:
- JOB="Autotools (Ubuntu Artful)"
- DISTRO=ubuntu-artful
- SCRIPT="autotools.sh"
- BUILD_ENV="-e CC=gcc -e CXX=g++"
- script: build/docker/run.sh
env:
- JOB="Autotools (Ubuntu Xenial)"
- DISTRO=ubuntu-xenial
- SCRIPT="autotools.sh"
- BUILD_ENV="-e CC=gcc -e CXX=g++"
- script: build/docker/run.sh
env:
- JOB="Autotools (Ubuntu Trusty)"
- DISTRO=ubuntu-trusty
- SCRIPT="autotools.sh"
- BUILD_ENV="-e CC=gcc -e CXX=g++"
# ------------------------- phase: dist -------------------------
- script: build/docker/run.sh
env:
- JOB="make dist"
- SCRIPT="make-dist.sh"
- BUILD_ENV="-e CC=gcc -e CXX=g++"
- script: build/docker/run.sh
env:
- JOB="Debian Packages"
- SCRIPT="dpkg.sh"
- BUILD_ENV="-e CC=gcc -e CXX=g++"

View file

@ -17,7 +17,14 @@
# under the License. # under the License.
# #
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.1)
# CMake 3.1 supports C++ standards selection with CMAKE_CXX_STANDARD
# If you need CMake 3.1+ for Ubuntu 14.04, try
# https://launchpad.net/~george-edison55/+archive/ubuntu/cmake-3.x
# If you need CMake 3.1+ for debian "jessie", get it from jessie-backports
# Otherwise
# http://cmake.org
project("Apache Thrift") project("Apache Thrift")

View file

@ -1,49 +1,91 @@
## How to contribute # How to Contribute #
1. Help to review and verify existing patches
1. Make sure your issue is not all ready in the [Jira issue tracker](http://issues.apache.org/jira/browse/THRIFT)
1. If not, create a ticket describing the change you're proposing in the [Jira issue tracker](http://issues.apache.org/jira/browse/THRIFT)
1. Contribute your patch using one of the two methods below
### Contributing via a patch Thank you for your interest in contributing to the Apache Thrift project! Information on why and how to contribute is available on the Apache Software Foundation (ASF) web site. In particular, we recommend the following to become acquainted with Apache Contributions:
1. Check out the latest version of the source code
* git clone https://git-wip-us.apache.org/repos/asf/thrift.git thrift
1. Modify the source to include the improvement/bugfix
* Remember to provide *tests* for all submited changes
* When bugfixing: add test that will isolate bug *before* applying change that fixes it
* Verify that you follow [Thrift Coding Standards](/docs/coding_standards) (you can run 'make style', which ensures proper format for some languages)
1. Create a patch from project root directory (e.g. you@dev:~/thrift $ ):
* git diff > ../thrift-XXX-my-new-feature.patch
1. Attach the newly generated patch to the issue
1. Wait for other contributors or committers to review your new addition
1. Wait for a committer to commit your patch
### Contributing via GitHub pull requests
1. Create a fork for http://github.com/apache/thrift
1. Create a branch for your changes(best practice is issue as branch name, e.g. THRIFT-9999)
1. Modify the source to include the improvement/bugfix
* Remember to provide *tests* for all submited changes
* When bugfixing: add test that will isolate bug *before* applying change that fixes it
* Verify that you follow [Thrift Coding Standards](/docs/coding_standards) (you can run 'make style', which ensures proper format for some languages)
* Verify that your change works on other platforms by adding a GitHub service hook to [Travis CI](http://docs.travis-ci.com/user/getting-started/#Step-one%3A-Sign-in) and [AppVeyor](http://www.appveyor.com/docs)
1. Commit and push changes to your branch (please use issue name and description as commit title, e.g. THRIFT-9999 make it perfect)
1. Issue a pull request with the jira ticket number you are working on in it's name
1. Wait for other contributors or committers to review your new addition
1. Wait for a committer to commit your patch
### More info
Plenty of information on why and how to contribute is available on the Apache Software Foundation (ASF) web site. In particular, we recommend the following:
* [Contributors Tech Guide](http://www.apache.org/dev/contributors) * [Contributors Tech Guide](http://www.apache.org/dev/contributors)
* [Get involved!](http://www.apache.org/foundation/getinvolved.html) * [Get involved!](http://www.apache.org/foundation/getinvolved.html)
* [Legal aspects on Submission of Contributions (Patches)](http://www.apache.org/licenses/LICENSE-2.0.html#contributions) * [Legal aspects on Submission of Contributions (Patches)](http://www.apache.org/licenses/LICENSE-2.0.html#contributions)
## If you want to review open issues... ##
1. Review the [GitHub Pull Request Backlog](https://github.com/apache/thrift/pulls). Code reviews are open to all.
2. Review the [Jira issue tracker](http://issues.apache.org/jira/browse/THRIFT). You can search for tickets relating to languages you are interested in or currently using with thrift, for example a Jira search (Issues -> Search For Issues) query of ``project = THRIFT AND component in ("Erlang - Library") and status not in (resolved, closed)`` will locate all the open Erlang Library issues.
## If you discovered a defect... ##
1. Check to see if the issue is already in the [Jira issue tracker](http://issues.apache.org/jira/browse/THRIFT).
1. If not, create a ticket describing the change you're proposing in the Jira issue tracker.
1. Contribute your code changes using the GitHub pull request method:
## Contributing via GitHub pull requests ##
This is the preferred method of submitting changes. When you submit a pull request through github, it activates the continuous integration (CI) build systems at Appveyor and Travis to build your changes on a variety of Windows and Linux configurations and run all the test suites.
1. Create a fork in your GitHub account of http://github.com/apache/thrift
1. Clone the fork to your development system.
1. Create a branch for your changes (best practice is issue as branch name, e.g. THRIFT-9999).
1. Modify the source to include the improvement/bugfix, and:
* Remember to provide *tests* for all submitted changes!
* Use test-driven development (TDD): add a test that will isolate the bug *before* applying a change that fixes it.
* Verify that you follow [Thrift Coding Standards](/docs/coding_standards) (you can run 'make style', which ensures proper format for some languages).
* [*optional*] Verify that your change works on other platforms by adding a GitHub service hook to [Travis CI](http://docs.travis-ci.com/user/getting-started/#Step-one%3A-Sign-in) and [AppVeyor](http://www.appveyor.com/docs). You can use this technique to run the Thrift CI jobs in your account to check your changes before they are made public. Every GitHub pull request into Thrift will run the full CI build and test suite on your changes.
1. Squash your changes to a single commit. This is very important as it makes the process of applying your commit upstream much easier.
1. Commit and push changes to your branch (please use issue name and description as commit title, e.g. "THRIFT-9999: make it perfect").
1. Use GitHub to create a pull request going from your branch to apache:master. Ensure that the Jira ticket number is at the beginning of the title of your pull request, same as the commit title.
1. Wait for other contributors or committers to review your new addition, and for a CI build to complete.
1. Wait for a committer to commit your patch. You can nudge the committers if necessary by sending a message to the [Apache Thrift mailing list](https://thrift.apache.org/mailing).
## Contributing via Patch ##
Some changes do not require a build, for example in documentation. For changes that are not code or build related, you can submit a patch on Jira for review. To create a patch from changes in your local directory:
git diff > ../THRIFT-NNNN.patch
then wait for contributors or committers to review your changes, and then for a committer to apply your patch.
## GitHub recipes for Pull Requests ##
Sometimes commmitters may ask you to take actions in your pull requests. Here are some recipes that will help you accomplish those requests. These examples assume you are working on Jira issue THRIFT-9999. You should also be familiar with the [upstream](https://help.github.com/articles/syncing-a-fork/) repository concept.
### Squash your changes ###
If you have not submitted a pull request yet, or if you have not yet rebased your existing pull request, you can squash all your commits down to a single commit. This makes life easier for the committers. If your pull request on GitHub has more than one commit, you should do this.
1. Use the command ``git log`` to identify how many commits you made since you began.
2. Use the command ``git rebase -i HEAD~N`` where N is the number of commits.
3. Leave "pull" in the first line.
4. Change all other lines from "pull" to "fixup".
5. All your changes are now in a single commit.
If you already have a pull request outstanding, you will need to do a "force push" to overwrite it since you changed your commit history:
git push -u origin THRIFT-9999 --force
A more detailed walkthrough of a squash can be found at [Git Ready](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html).
### Rebase your pull request ###
If your pull request has a conflict with master, it needs to be rebased:
git checkout THRIFT-9999
git rebase upstream master
(resolve any conflicts, make sure it builds)
git push -u origin THRIFT-9999 --force
### Fix a bad merge ###
If your pull request contains commits that are not yours, then you should use the following technique to fix the bad merge in your branch:
git checkout master
git pull upstream master
git checkout -b THRIFT-9999-take-2
git cherry-pick ...
(pick only your commits from your original pull request in ascending chronological order)
squash your changes to a single commit if there is more than one (see above)
git push -u origin THRIFT-9999-take-2:THRIFT-9999
This procedure will apply only your commits in order to the current master, then you will squash them to a single commit, and then you force push your local THRIFT-9999-take-2 into remote THRIFT-9999 which represents your pull request, replacing all the commits with the new one.

View file

@ -1,61 +0,0 @@
# 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.
#
# Goal: provide a thrift-compiler Docker image
#
# Usage:
# docker run -v "${PWD}:/data" thrift/thrift-compiler -gen cpp -o /data/ /data/test/ThriftTest.thrift
#
# further details on docker for thrift is here build/docker/
#
# TODO: push to apache/thrift-compiler instead of thrift/thrift-compiler
FROM debian:jessie
MAINTAINER Apache Thrift <dev@thrift.apache.org>
ENV DEBIAN_FRONTEND noninteractive
ADD . /thrift
RUN buildDeps=" \
flex \
bison \
g++ \
make \
cmake \
curl \
"; \
apt-get update && apt-get install -y --no-install-recommends $buildDeps \
&& mkdir /tmp/cmake-build && cd /tmp/cmake-build \
&& cmake \
-DBUILD_COMPILER=ON \
-DBUILD_LIBRARIES=OFF \
-DBUILD_TESTING=OFF \
-DBUILD_EXAMPLES=OFF \
/thrift \
&& cmake --build . --config Release \
&& make install \
&& curl -k -sSL "https://storage.googleapis.com/golang/go1.5.2.linux-amd64.tar.gz" -o /tmp/go.tar.gz \
&& tar xzf /tmp/go.tar.gz -C /tmp \
&& cp /tmp/go/bin/gofmt /usr/bin/gofmt \
&& apt-get purge -y --auto-remove $buildDeps \
&& apt-get clean \
&& rm -rf /tmp/* \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["thrift"]

305
vendor/github.com/apache/thrift/LANGUAGES.md generated vendored Normal file
View file

@ -0,0 +1,305 @@
# Apache Thrift Language Support #
Last Modified: 2017-10-05<br>
Version: 0.10.0+
Thrift supports many programming languages and has an impressive test suite that exercises most of the languages, protocols, and transports that represents a matrix of thousands of possible combinations. Each language typically has a minimum required version as well as support libraries - some mandatory and some optional. All of this information is provided below to help you assess whether you can use Apache Thrift with your project. Obviously this is a complex matrix to maintain and may not be correct in all cases - if you spot an error please inform the developers using the mailing list.
Apache Thrift has a choice of two build systems. The `autoconf` build system is the most complete build and is used to build all supported languages. The `cmake` build system has been designated by the project to replace `autoconf` however this transition will take quite some time to complete.
The Language/Library Levels indicate the minimum and maximum versions that are used in the [continuous integration environments](build/docker/README.md) (Appveyor, Travis) for Apache Thrift. Note that while a language may contain support for protocols, transports, and servers, the extent to which each is tested as part of the overall build process varies. The definitive integration test for the project is called the "cross" test which executes a test matrix with clients and servers communicating across languages.
<table style="font-size: 65%; padding: 1px;">
<thead>
<tr>
<th rowspan=2>Language</th>
<th colspan=2 align=center>Build Systems</th>
<th colspan=2 align=center>Lang/Lib Levels</th>
<th colspan=6 align=center>Low-Level Transports</th>
<th colspan=3 align=center>Transport Wrappers</th>
<th colspan=4 align=center>Protocols</th>
<th colspan=5 align=center>Servers</th>
<th rowspan=2>Open Issues</th>
</tr>
<tr>
<!-- Build Systems ---------><th>autoconf</th><th>cmake</th>
<!-- Lang/Lib Levels -------><th>Min</th><th>Max</th>
<!-- Low-Level Transports --><th><a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Domain</a></th><th>&nbsp;File&nbsp;</th><th>Memory</th><th>&nbsp;Pipe&nbsp;</th><th>Socket</th><th>&nbsp;TLS&nbsp;</th>
<!-- Transport Wrappers ----><th>Framed</th><th>&nbsp;http&nbsp;</th><th>&nbsp;zlib&nbsp;</th>
<!-- Protocols -------------><th><a href="doc/specs/thrift-binary-protocol.md">Binary</a></th><th><a href="doc/specs/thrift-compact-protocol.md">Compact</a></th><th>&nbsp;JSON&nbsp;</th><th>Multiplex</th>
<!-- Servers ---------------><th>Forking</th><th>Nonblocking</th><th>Simple</th><th>Threaded</th><th>ThreadPool</th>
</tr>
</thead>
<tbody>
<tr align=center>
<td align=left><a href="lib/as3/README.md">ActionScript</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>ActionScript 3</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/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>
<!-- Transport Wrappers ----><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>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313722">ActionScript</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/c_glib/README.md">C (glib)</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Language Levels -------><td>2.40.2</td><td>2.54.0</td>
<!-- Low-Level Transports --><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><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/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></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/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><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/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313854">C (glib)</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/cpp/README.md">C++</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Language Levels -------><td colspan=2>C++98, gcc </td>
<!-- Low-Level Transports --><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><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>
<!-- Servers ---------------><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><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312313">C++</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/csharp/README.md">C#</a></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>.NET&nbsp;3.5 / mono&nbsp;3.2.8.0</td><td>.NET&nbsp;4.6.1 / mono&nbsp;4.6.2.7</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/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/cred.png" alt=""/></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>
<!-- Servers ---------------><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/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312362">C# (.NET)</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/cocoa/README.md">Cocoa</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>unknown</td>
<!-- Low-Level Transports --><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><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/cred.png" alt=""/></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/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><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 align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312398">Cocoa</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/d/README.md">D</a></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>2.070.2</td><td>2.076.0</td>
<!-- Low-Level Transports --><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><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/cred.png" alt=""/></td>
<!-- Servers ---------------><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><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12317904">D</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/dart/README.md">Dart</a></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.20.1</td><td>1.24.2</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/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>
<!-- 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/cred.png" alt=""/></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>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12328006">Dart</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/delphi/README.md">Delphi</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>2010</td><td>unknown</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/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>
<!-- 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/cred.png" alt=""/></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>
<!-- Servers ---------------><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/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12316601">Delphi</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/netcore/README.md">.NET Core</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>2.0.0</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/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/cred.png" alt=""/></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>
<!-- Servers ---------------><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/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12331176">.NET Core</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/erl/README.md">Erlang</a></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>R16B03</td><td>20.0.4</td>
<!-- Low-Level Transports --><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><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/cred.png" alt=""/></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>
<!-- Servers ---------------><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/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312390">Erlang</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/go/README.md">Go</a></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.2.1</td><td>1.8.3</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>
<!-- 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>
<!-- Servers ---------------><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/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12314307">Go</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/hs/README.md">Haskell</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Language Levels -------><td>7.6.3</td><td>8.0.2</td>
<!-- Low-Level Transports --><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><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/cred.png" alt=""/></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/cred.png" alt=""/></td>
<!-- Servers ---------------><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/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312704">Haskell</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/haxe/README.md">Haxe</a></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 colspan=2>3.2.1</td>
<!-- Low-Level Transports --><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/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></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/cred.png" alt=""/></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>
<!-- Servers ---------------><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/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12324347">Haxe</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/java/README.md">Java (SE)</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Language Levels -------><td>1.7.0_151</td><td>1.8.0_144</td>
<!-- Low-Level Transports --><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><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>
<!-- 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>
<!-- Servers ---------------><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><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312314">Java SE</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/javame/README.md">Java (ME)</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>unknown</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/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><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/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313759">Java ME</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/js/README.md">Javascript</a></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 colspan=2>unknown</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/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/cgrn.png" alt="Yes"/></td>
<!-- Transport Wrappers ----><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>
<!-- Protocols -------------><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/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313418">Javascript</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/lua/README.md">Lua</a></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>5.1.5</td><td>5.3.3</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/cred.png" alt=""/></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/cred.png" alt=""/></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/cred.png" alt=""/></td>
<!-- Servers ---------------><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/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12322659">Lua</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/nodejs/README.md">node.js</a></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>4.2.6</td><td>8.8.1</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/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/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/cred.png" alt=""/></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>
<!-- Servers ---------------><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/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12314320">node.js</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/ocaml/README.md">OCaml</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>4.02.3</td><td>4.04.0</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/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>
<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><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/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313660">OCaml</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/perl/README.md">Perl</a></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>5.18.2</td><td>5.26.0</td>
<!-- Low-Level Transports --><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/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/cred.png" alt=""/></td>
<!-- Protocols -------------><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>
<!-- Servers ---------------><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/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312312">Perl</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/php/README.md">PHP</a></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>5.5.9</td><td>7.1.8</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/cred.png" alt=""/></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>
<!-- Servers ---------------><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/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312431">PHP</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/py/README.md">Python</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Language Levels -------><td>2.7.6, 3.4.3</td><td>2.7.14, 3.6.3</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/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/cgrn.png" alt="Yes"/></td>
<!-- Transport Wrappers ----><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>
<!-- 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>
<!-- Servers ---------------><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/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312315">Python</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/rb/README.md">Ruby</a></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.9.3p484</td><td>2.3.3p222</td>
<!-- Low-Level Transports --><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/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/cred.png" alt=""/></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>
<!-- Servers ---------------><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><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312316">Ruby</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/rs/README.md">Rust</a></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.15.1</td><td>1.18.0</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/cred.png" alt=""/></td>
<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></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/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><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 align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12331420">Rust</a></td>
</tr>
<tr align=center>
<td align=left><a href="lib/st/README.md">Smalltalk</a></td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>unknown</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/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>
<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313861">Smalltalk</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<th rowspan=2>Language</th>
<!-- Build Systems ---------><th>autoconf</th><th>cmake</th>
<!-- Lang/Lib Levels -------><th>Min</th><th>Max</th>
<!-- Low-Level Transports --><th><a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Domain</a></th></th><th>&nbsp;File&nbsp;</th><th>Memory</th><th>&nbsp;Pipe&nbsp;</th><th>Socket</th><th>&nbsp;TLS&nbsp;</th>
<!-- Transport Wrappers ----><th>Framed</th><th>&nbsp;http&nbsp;</th><th>&nbsp;zlib&nbsp;</th>
<!-- Protocols -------------><th><a href="doc/specs/thrift-binary-protocol.md">Binary</a></th><th><a href="doc/specs/thrift-compact-protocol.md">Compact</a></th><th>&nbsp;JSON&nbsp;</th><th>Multiplex</th>
<!-- Servers ---------------><th>Forking</th><th>Nonblocking</th><th>Simple</th><th>Threaded</th><th>ThreadPool</th>
<th rowspan=2>Open Issues</th>
</tr>
<tr>
<th colspan=2 align=center>Build Systems</th>
<th colspan=2 align=center>Lang/Lib Levels</th>
<th colspan=6 align=center>Low-Level Transports</th>
<th colspan=3 align=center>Transport Wrappers</th>
<th colspan=4 align=center>Protocols</th>
<th colspan=5 align=center>Servers</th>
</tr>
</tfoot>
</table>

View file

@ -43,7 +43,7 @@ dist-hook:
find $(distdir) -type d \( -iname ".svn" -or -iname ".git" \) | xargs rm -rf find $(distdir) -type d \( -iname ".svn" -or -iname ".git" \) | xargs rm -rf
print-version: print-version:
@echo $(VERSION) @echo $(PACKAGE_VERSION)
.PHONY: precross cross .PHONY: precross cross
precross-%: all precross-%: all
@ -54,7 +54,7 @@ empty :=
space := $(empty) $(empty) space := $(empty) $(empty)
comma := , comma := ,
CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_D@ @MAYBE_JAVA@ @MAYBE_CSHARP@ @MAYBE_PYTHON@ @MAYBE_PY3@ @MAYBE_RUBY@ @MAYBE_HASKELL@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ @MAYBE_ERLANG@ @MAYBE_LUA@ CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_D@ @MAYBE_JAVA@ @MAYBE_CSHARP@ @MAYBE_PYTHON@ @MAYBE_PY3@ @MAYBE_RUBY@ @MAYBE_HASKELL@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ @MAYBE_ERLANG@ @MAYBE_LUA@ @MAYBE_RS@ @MAYBE_DOTNETCORE@
CROSS_LANGS_COMMA_SEPARATED = $(subst $(space),$(comma),$(CROSS_LANGS)) CROSS_LANGS_COMMA_SEPARATED = $(subst $(space),$(comma),$(CROSS_LANGS))
if WITH_PY3 if WITH_PY3
@ -123,7 +123,7 @@ EXTRA_DIST = \
doap.rdf \ doap.rdf \
package.json \ package.json \
sonar-project.properties \ sonar-project.properties \
Dockerfile \ LANGUAGES.md \
LICENSE \ LICENSE \
CHANGES \ CHANGES \
NOTICE \ NOTICE \

View file

@ -1,5 +1,5 @@
Apache Thrift Apache Thrift
Copyright 2006-2010 The Apache Software Foundation. Copyright 2006-2017 The Apache Software Foundation.
This product includes software developed at This product includes software developed at
The Apache Software Foundation (http://www.apache.org/). The Apache Software Foundation (http://www.apache.org/).

View file

@ -1,9 +1,27 @@
Apache Thrift Apache Thrift
============= =============
+[![Build Status](https://travis-ci.org/apache/thrift.svg?branch=master)](https://travis-ci.org/apache/thrift) Last Modified: 2014-03-16
- +[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/e2qks7enyp9gw7ma?svg=true)](https://ci.appveyor.com/project/apache/thrift)
License
=======
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.
Introduction Introduction
============ ============
@ -15,15 +33,22 @@ level processing. The code generation system takes a simple definition
language as its input and generates code across programming languages that language as its input and generates code across programming languages that
uses the abstracted stack to build interoperable RPC clients and servers. uses the abstracted stack to build interoperable RPC clients and servers.
![Apache Thrift Layered Architecture](doc/images/thrift-layers.png)
Thrift makes it easy for programs written in different programming
languages to share data and call remote procedures. With support
for [over 20 programming languages](LANGUAGES.md), chances are Thrift
supports the ones that you currently use.
Thrift is specifically designed to support non-atomic version changes Thrift is specifically designed to support non-atomic version changes
across client and server code. across client and server code.
For more details on Thrift's design and implementation, take a gander at For more details on Thrift's design and implementation, take a gander at
the Thrift whitepaper included in this distribution or at the README.md files the Thrift whitepaper included in this distribution or at the README.md file
in your particular subdirectory of interest. in your particular subdirectory of interest.
Hierarchy Project Hierarchy
========= =================
thrift/ thrift/
@ -42,6 +67,7 @@ thrift/
php/ php/
py/ py/
rb/ rb/
...
test/ test/
@ -145,22 +171,3 @@ To run the cross-language test suite, please run:
This will run a set of tests that use different language clients and This will run a set of tests that use different language clients and
servers. servers.
License
=======
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.

View file

@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "Thrift" s.name = "Thrift"
s.version = "0.10.0" s.version = "1.0.0"
s.summary = "Apache Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC." s.summary = "Apache Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC."
s.description = <<-DESC s.description = <<-DESC
The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages. The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.
@ -13,6 +13,6 @@ The Apache Thrift software framework, for scalable cross-language services devel
s.osx.deployment_target = '10.8' s.osx.deployment_target = '10.8'
s.ios.framework = 'CFNetwork' s.ios.framework = 'CFNetwork'
s.osx.framework = 'CoreServices' s.osx.framework = 'CoreServices'
s.source = { :git => "https://github.com/apache/thrift.git", :tag => "thrift-0.10.0" } s.source = { :git => "https://github.com/apache/thrift.git", :tag => "thrift-1.0.0" }
s.source_files = 'lib/cocoa/src/**/*.{h,m,swift}' s.source_files = 'lib/cocoa/src/**/*.{h,m,swift}'
end end

View file

@ -1,3 +1,4 @@
#
# 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
# distributed with this work for additional information # distributed with this work for additional information
@ -18,76 +19,83 @@
# build Apache Thrift on AppVeyor - https://ci.appveyor.com # build Apache Thrift on AppVeyor - https://ci.appveyor.com
shallow_clone: true version: '1.0.0-dev.{build}'
clone_depth: 10
shallow_clone: true
version: '{build}'
os: os:
# - Windows Server 2012 R2 - Visual Studio 2015
- Visual Studio 2015
cache:
- C:\projects\thrift\buildcache -> build\appveyor\MSVC-appveyor-install.bat
- C:\ProgramData\chocolatey\lib -> build\appveyor\MSVC-appveyor-install.bat
- C:\msys64\var\cache\pacman -> build\appveyor\MSYS-appveyor-install.bat
environment: environment:
BOOST_ROOT: C:\Libraries\boost_1_59_0 matrix:
BOOST_LIBRARYDIR: C:\Libraries\boost_1_59_0\lib64-msvc-14.0 - PROFILE: MSVC2010
# Unfurtunately, this version needs manual update because old versions are quickly deleted. PLATFORM: x86
ANT_VERSION: 1.9.7 CONFIGURATION: Debug
BOOST_VERSION: 1.54.0
LIBEVENT_VERSION: 2.0.22
QT_VERSION: 5.6
ZLIB_VERSION: 1.2.8
DISABLED_TESTS: StressTestNonBlocking
- PROFILE: MSVC2015
PLATFORM: x64
CONFIGURATION: Release
BOOST_VERSION: 1.64.0
LIBEVENT_VERSION: 2.0.22
PYTHON_VERSION: 3.6
QT_VERSION: 5.8
ZLIB_VERSION: 1.2.11
DISABLED_TESTS: StressTestNonBlocking
- PROFILE: MINGW
PLATFORM: x64
CONFIGURATION: Release
matrix:
fast_finish: true
install: install:
- '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64' - cd %APPVEYOR_BUILD_FOLDER%
- cd \ - call build\appveyor\%PROFILE:~0,4%-appveyor-install.bat
# Zlib - refreshenv
- appveyor DownloadFile https://github.com/madler/zlib/archive/v1.2.8.tar.gz
- 7z x v1.2.8.tar.gz -so | 7z x -si -ttar > nul
- cd zlib-1.2.8
- cmake -G "Visual Studio 14 2015 Win64" .
- cmake --build . --config release
- cd ..
# OpenSSL
- C:\Python35-x64\python %APPVEYOR_BUILD_FOLDER%\build\appveyor\download_openssl.py
- ps: Start-Process "Win64OpenSSL.exe" -ArgumentList "/silent /verysilent /sp- /suppressmsgboxes" -Wait
# Libevent
- appveyor DownloadFile https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz
- 7z x libevent-2.0.22-stable.tar.gz -so | 7z x -si -ttar > nul
- cd libevent-2.0.22-stable
- nmake -f Makefile.nmake
- mkdir lib
- move *.lib lib\
- move WIN32-Code\event2\* include\event2\
- move *.h include\
- cd ..
- appveyor-retry cinst -y winflexbison
- appveyor DownloadFile http://www.us.apache.org/dist/ant/binaries/apache-ant-%ANT_VERSION%-bin.zip
- 7z x apache-ant-%ANT_VERSION%-bin.zip > nul
- cd %APPVEYOR_BUILD_FOLDER%
# TODO: Enable Haskell build
# - cinst HaskellPlatform -version 2014.2.0.0
build_script: build_script:
- set PATH=C:\ProgramData\chocolatey\bin;C:\apache-ant-%ANT_VERSION%\bin;%PATH% - cd %APPVEYOR_BUILD_FOLDER%
- set JAVA_HOME=C:\Program Files\Java\jdk1.7.0 - call build\appveyor\%PROFILE:~0,4%-appveyor-build.bat
- set PATH=%JAVA_HOME%\bin;%PATH%
# - set PATH=%PATH%;C:\Program Files (x86)\Haskell Platform\2014.2.0.0\bin test_script:
# - set PATH=%PATH%;C:\Program Files (x86)\Haskell Platform\2014.2.0.0\lib\extralibs\bin - cd %APPVEYOR_BUILD_FOLDER%
- set PATH=C:\Python27-x64\scripts;C:\Python27-x64;%PATH% - call build\appveyor\%PROFILE:~0,4%-appveyor-test.bat
- pip install ipaddress backports.ssl_match_hostname tornado twisted
- mkdir cmake-build
- cd cmake-build # artifact capture disabled as it might increase service cost for little gain:
- cmake -G "Visual Studio 14 2015 Win64" -DWITH_SHARED_LIB=OFF -DLIBEVENT_ROOT=C:\libevent-2.0.22-stable -DZLIB_INCLUDE_DIR=C:\zlib-1.2.8 -DZLIB_LIBRARY=C:\zlib-1.2.8\release\zlibstatic.lib -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" .. #
- findstr /b /e BUILD_COMPILER:BOOL=ON CMakeCache.txt # artifacts:
- findstr /b /e BUILD_CPP:BOOL=ON CMakeCache.txt # - path: local-thrift-inst
- findstr /b /e BUILD_JAVA:BOOL=ON CMakeCache.txt # name: cmake installed content
- findstr /b /e BUILD_PYTHON:BOOL=ON CMakeCache.txt # type: zip
# - findstr /b /e BUILD_C_GLIB:BOOL=ON CMakeCache.txt #
# - findstr /b /e BUILD_HASKELL:BOOL=ON CMakeCache.txt # - path: local-thrift-build\Testing
- findstr /b /e BUILD_TESTING:BOOL=ON CMakeCache.txt # name: ctest output
# - cmake --build . # type: zip
- cmake --build . --config Release
# TODO: Fix cpack # RDP support: use one or the other...
# - cpack #
# TODO: Run more tests # enables RDP for each build job so you can inspect the environment at the beginning of the job:
# CTest fails to invoke ant seemingly due to "ant.bat" v.s. "ant" (shell script) conflict. # init:
# Currently, everything that involves OpenSSL seems to hang forever on our Appveyor setup. # - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# Also a few C++ tests hang (on Appveyor or on Windows in general). #
- ctest -C Release --timeout 600 -VV -E "(StressTestNonBlocking|PythonTestSSLSocket|python_test$|^Java)" # enables RDP at the end of the build job so you can login and re-run
# TODO make it perfect ;-r # commands to see why something failed...
#on_finish:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
#
# also need:
# environment:
# APPVEYOR_RDP_PASSWORD: thr1FT2345$xyzZ

View file

@ -46,9 +46,12 @@ if [ "$AUTOMAKE_VERSION" \< "1.13" ]; then
exit 1 exit 1
fi fi
set -e
autoscan autoscan
$LIBTOOLIZE --copy --automake $LIBTOOLIZE --copy --automake
aclocal -I ./aclocal aclocal -I ./aclocal
autoheader autoheader
sed '/undef VERSION/d' config.hin > config.hin2
mv config.hin2 config.hin
autoconf autoconf
automake --copy --add-missing --foreign automake --copy --add-missing --foreign

View file

@ -1,6 +1,5 @@
{ {
"name": "thrift", "name": "thrift",
"version": "0.10.0",
"homepage": "https://git-wip-us.apache.org/repos/asf/thrift.git", "homepage": "https://git-wip-us.apache.org/repos/asf/thrift.git",
"authors": [ "authors": [
"Apache Thrift <dev@thrift.apache.org>" "Apache Thrift <dev@thrift.apache.org>"

View file

@ -24,7 +24,7 @@
"minimum-stability": "dev", "minimum-stability": "dev",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "0.10.0" "dev-master": "1.0.x-dev"
} }
} }
} }

View file

@ -20,7 +20,7 @@
AC_PREREQ(2.65) AC_PREREQ(2.65)
AC_CONFIG_MACRO_DIR([./aclocal]) AC_CONFIG_MACRO_DIR([./aclocal])
AC_INIT([thrift], [0.10.0]) AC_INIT([thrift], [1.0.0-dev])
AC_CONFIG_AUX_DIR([.]) AC_CONFIG_AUX_DIR([.])
@ -83,6 +83,9 @@ AS_IF([test "x$D_IMPORT_PREFIX" = x], [D_IMPORT_PREFIX="${includedir}/d2"])
AC_ARG_VAR([DMD_LIBEVENT_FLAGS], [DMD flags for linking libevent (auto-detected if not set).]) AC_ARG_VAR([DMD_LIBEVENT_FLAGS], [DMD flags for linking libevent (auto-detected if not set).])
AC_ARG_VAR([DMD_OPENSSL_FLAGS], [DMD flags for linking OpenSSL (auto-detected if not set).]) AC_ARG_VAR([DMD_OPENSSL_FLAGS], [DMD flags for linking OpenSSL (auto-detected if not set).])
AC_ARG_VAR([THRIFT], [Path to the thrift tool (needed for cross-compilation).])
AS_IF([test "x$THRIFT" = x], [THRIFT=`pwd`/compiler/cpp/thrift])
AC_PROG_CC AC_PROG_CC
AC_PROG_CPP AC_PROG_CPP
AC_PROG_CXX AC_PROG_CXX
@ -100,6 +103,9 @@ AC_PROG_RANLIB
AC_LANG([C++]) AC_LANG([C++])
AX_CXX_COMPILE_STDCXX_11([noext], [optional]) AX_CXX_COMPILE_STDCXX_11([noext], [optional])
if test "$ac_success" = "no"; then
CXXFLAGS="$CXXFLAGS -Wno-variadic-macros -Wno-long-long -Wno-c++11-long-long"
fi
AM_EXTRA_RECURSIVE_TARGETS([style]) AM_EXTRA_RECURSIVE_TARGETS([style])
AC_SUBST(CPPSTYLE_CMD, 'find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;') AC_SUBST(CPPSTYLE_CMD, 'find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;')
@ -116,9 +122,11 @@ if test "$enable_libs" = "no"; then
with_java="no" with_java="no"
with_csharp="no" with_csharp="no"
with_python="no" with_python="no"
with_py3="no"
with_ruby="no" with_ruby="no"
with_haskell="no" with_haskell="no"
with_haxe="no" with_haxe="no"
with_dotnetcore="no"
with_perl="no" with_perl="no"
with_php="no" with_php="no"
with_php_extension="no" with_php_extension="no"
@ -128,9 +136,9 @@ if test "$enable_libs" = "no"; then
with_d="no" with_d="no"
with_nodejs="no" with_nodejs="no"
with_lua="no" with_lua="no"
with_rs="no"
fi fi
AX_THRIFT_LIB(cpp, [C++], yes) AX_THRIFT_LIB(cpp, [C++], yes)
have_cpp=no have_cpp=no
if test "$with_cpp" = "yes"; then if test "$with_cpp" = "yes"; then
@ -145,8 +153,6 @@ if test "$with_cpp" = "yes"; then
have_cpp="yes" have_cpp="yes"
fi fi
AX_CHECK_OPENSSL()
AX_LIB_EVENT([1.0]) AX_LIB_EVENT([1.0])
have_libevent=$success have_libevent=$success
@ -197,6 +203,12 @@ if test "$with_c_glib" = "yes"; then
fi fi
AM_CONDITIONAL(WITH_C_GLIB, [test "$have_glib2" = "yes" -a "$have_gobject2" = "yes"]) AM_CONDITIONAL(WITH_C_GLIB, [test "$have_glib2" = "yes" -a "$have_gobject2" = "yes"])
echo "OpenSSL check"
if test "$have_cpp" = "yes" -o "$have_c_glib" = "yes"; then
echo "Have cpp or c so we check for OpenSSL"
AX_CHECK_OPENSSL()
fi
AX_THRIFT_LIB(csharp, [C#], yes) AX_THRIFT_LIB(csharp, [C#], yes)
if test "$with_csharp" = "yes"; then if test "$with_csharp" = "yes"; then
PKG_CHECK_MODULES(MONO, mono >= 2.11.0, mono_2_11=yes, mono_2_11=no) PKG_CHECK_MODULES(MONO, mono >= 2.11.0, mono_2_11=yes, mono_2_11=no)
@ -294,6 +306,7 @@ AM_CONDITIONAL(WITH_TWISTED_TEST, [test "$have_trial" = "yes"])
# Find "python3" executable. # Find "python3" executable.
# It's distro specific and far from ideal but needed to cross test py2-3 at once. # It's distro specific and far from ideal but needed to cross test py2-3 at once.
# TODO: find "python2" if it's 3.x # TODO: find "python2" if it's 3.x
have_py3="no"
if python --version 2>&1 | grep -q "Python 2"; then if python --version 2>&1 | grep -q "Python 2"; then
AC_PATH_PROGS([PYTHON3], [python3 python3.5 python35 python3.4 python34]) AC_PATH_PROGS([PYTHON3], [python3 python3.5 python35 python3.4 python34])
if test -n "$PYTHON3"; then if test -n "$PYTHON3"; then
@ -389,6 +402,7 @@ if test "$with_go" = "yes"; then
if [[ -x "$GO" ]] ; then if [[ -x "$GO" ]] ; then
AS_IF([test -n "$GO"],[ AS_IF([test -n "$GO"],[
ax_go_version="1.4" ax_go_version="1.4"
ax_go17_version="1.7"
AC_MSG_CHECKING([for Go version]) AC_MSG_CHECKING([for Go version])
golang_version=`$GO version 2>&1 | $SED -e 's/\(go \)\(version \)\(go\)\(@<:@0-9@:>@.@<:@0-9@:>@.@<:@0-9@:>@\)\(@<:@\*@:>@*\).*/\4/'` golang_version=`$GO version 2>&1 | $SED -e 's/\(go \)\(version \)\(go\)\(@<:@0-9@:>@.@<:@0-9@:>@.@<:@0-9@:>@\)\(@<:@\*@:>@*\).*/\4/'`
@ -401,6 +415,13 @@ if test "$with_go" = "yes"; then
: :
have_go="no" have_go="no"
]) ])
AX_COMPARE_VERSION([$golang_version],[lt],[$ax_go17_version],[
:
go_version_lt_17="yes"
],[
:
go_version_lt_17="no"
])
],[ ],[
AC_MSG_WARN([could not find Go ]) AC_MSG_WARN([could not find Go ])
have_go="no" have_go="no"
@ -408,7 +429,31 @@ if test "$with_go" = "yes"; then
fi fi
fi fi
AM_CONDITIONAL(WITH_GO, [test "$have_go" = "yes"]) AM_CONDITIONAL(WITH_GO, [test "$have_go" = "yes"])
AM_CONDITIONAL([GOVERSION_LT_17], [test "$go_version_lt_17" = "yes"])
AX_THRIFT_LIB(rs, [Rust], yes)
have_rs="no"
if test "$with_rs" = "yes"; then
AC_PATH_PROG([CARGO], [cargo])
AC_PATH_PROG([RUSTC], [rustc])
if [[ -x "$CARGO" ]] && [[ -x "$RUSTC" ]]; then
min_rustc_version="1.13"
AC_MSG_CHECKING([for rustc version])
rustc_version=`$RUSTC --version 2>&1 | $SED -e 's/\(rustc \)\([0-9]\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\2.\3/'`
AC_MSG_RESULT($rustc_version)
AC_SUBST([rustc_version],[$rustc_version])
AX_COMPARE_VERSION([$min_rustc_version],[le],[$rustc_version],[
:
have_rs="yes"
],[
:
have_rs="no"
])
fi
fi
AM_CONDITIONAL(WITH_RS, [test "$have_rs" = "yes"])
AX_THRIFT_LIB(haxe, [Haxe], yes) AX_THRIFT_LIB(haxe, [Haxe], yes)
if test "$with_haxe" = "yes"; then if test "$with_haxe" = "yes"; then
@ -420,6 +465,16 @@ fi
AM_CONDITIONAL(WITH_HAXE, [test "$have_haxe" = "yes"]) AM_CONDITIONAL(WITH_HAXE, [test "$have_haxe" = "yes"])
AX_THRIFT_LIB(dotnetcore, [.NET Core], yes)
if test "$with_dotnetcore" = "yes"; then
AC_PATH_PROG([DOTNETCORE], [dotnet])
if [[ -x "$DOTNETCORE" ]] ; then
AX_PROG_DOTNETCORE_VERSION( [2.0.0], have_dotnetcore="yes", have_dotnetcore="no")
fi
fi
AM_CONDITIONAL(WITH_DOTNETCORE, [test "$have_dotnetcore" = "yes"])
AX_THRIFT_LIB(d, [D], yes) AX_THRIFT_LIB(d, [D], yes)
if test "$with_d" = "yes"; then if test "$with_d" = "yes"; then
AX_DMD AX_DMD
@ -517,8 +572,8 @@ fi
AM_CONDITIONAL(WITH_TESTS, [test "$have_tests" = "yes"]) AM_CONDITIONAL(WITH_TESTS, [test "$have_tests" = "yes"])
AC_ARG_ENABLE([plugin], AC_ARG_ENABLE([plugin],
AS_HELP_STRING([--enable-plugin], [build compiler plugin support [default=yes]]), AS_HELP_STRING([--enable-plugin], [build compiler plugin support [default=no]]),
[], enable_plugin=yes [], enable_plugin=no
) )
have_plugin=yes have_plugin=yes
if test "$have_cpp" = "no" ; then if test "$have_cpp" = "no" ; then
@ -527,9 +582,7 @@ fi
if test "$enable_plugin" = "no"; then if test "$enable_plugin" = "no"; then
have_plugin="no" have_plugin="no"
fi fi
if test "$have_plugin" = "yes" ; then AC_CONFIG_LINKS([compiler/cpp/test/plugin/t_cpp_generator.cc:compiler/cpp/src/thrift/generate/t_cpp_generator.cc])
AC_CONFIG_LINKS([compiler/cpp/test/plugin/t_cpp_generator.cc:compiler/cpp/src/thrift/generate/t_cpp_generator.cc])
fi
AM_CONDITIONAL(WITH_PLUGIN, [test "$have_plugin" = "yes"]) AM_CONDITIONAL(WITH_PLUGIN, [test "$have_plugin" = "yes"])
AC_ARG_ENABLE([tutorial], AC_ARG_ENABLE([tutorial],
@ -608,7 +661,7 @@ AC_TYPE_UINT16_T
AC_TYPE_UINT32_T AC_TYPE_UINT32_T
AC_TYPE_UINT64_T AC_TYPE_UINT64_T
AC_TYPE_UINT8_T AC_TYPE_UINT8_T
AC_CHECK_TYPES([ptrdiff_t], [], [exit 1]) AC_CHECK_TYPES([ptrdiff_t], [], [echo "ptrdiff_t not found or g++ not installed - cannot continue" && exit 1])
AC_STRUCT_TM AC_STRUCT_TM
@ -757,6 +810,7 @@ AC_CONFIG_FILES([
lib/js/test/Makefile lib/js/test/Makefile
lib/json/Makefile lib/json/Makefile
lib/json/test/Makefile lib/json/test/Makefile
lib/netcore/Makefile
lib/nodejs/Makefile lib/nodejs/Makefile
lib/perl/Makefile lib/perl/Makefile
lib/perl/test/Makefile lib/perl/test/Makefile
@ -765,6 +819,8 @@ AC_CONFIG_FILES([
lib/dart/Makefile lib/dart/Makefile
lib/py/Makefile lib/py/Makefile
lib/rb/Makefile lib/rb/Makefile
lib/rs/Makefile
lib/rs/test/Makefile
lib/lua/Makefile lib/lua/Makefile
lib/xml/Makefile lib/xml/Makefile
lib/xml/test/Makefile lib/xml/test/Makefile
@ -778,6 +834,7 @@ AC_CONFIG_FILES([
test/haxe/Makefile test/haxe/Makefile
test/hs/Makefile test/hs/Makefile
test/lua/Makefile test/lua/Makefile
test/netcore/Makefile
test/php/Makefile test/php/Makefile
test/dart/Makefile test/dart/Makefile
test/perl/Makefile test/perl/Makefile
@ -785,6 +842,7 @@ AC_CONFIG_FILES([
test/py.twisted/Makefile test/py.twisted/Makefile
test/py.tornado/Makefile test/py.tornado/Makefile
test/rb/Makefile test/rb/Makefile
test/rs/Makefile
tutorial/Makefile tutorial/Makefile
tutorial/c_glib/Makefile tutorial/c_glib/Makefile
tutorial/cpp/Makefile tutorial/cpp/Makefile
@ -794,12 +852,14 @@ AC_CONFIG_FILES([
tutorial/hs/Makefile tutorial/hs/Makefile
tutorial/java/Makefile tutorial/java/Makefile
tutorial/js/Makefile tutorial/js/Makefile
tutorial/netcore/Makefile
tutorial/nodejs/Makefile tutorial/nodejs/Makefile
tutorial/dart/Makefile tutorial/dart/Makefile
tutorial/py/Makefile tutorial/py/Makefile
tutorial/py.twisted/Makefile tutorial/py.twisted/Makefile
tutorial/py.tornado/Makefile tutorial/py.tornado/Makefile
tutorial/rb/Makefile tutorial/rb/Makefile
tutorial/rs/Makefile
]) ])
if test "$have_cpp" = "yes" ; then MAYBE_CPP="cpp" ; else MAYBE_CPP="" ; fi if test "$have_cpp" = "yes" ; then MAYBE_CPP="cpp" ; else MAYBE_CPP="" ; fi
@ -834,6 +894,10 @@ if test "$have_erlang" = "yes" ; then MAYBE_ERLANG="erl" ; else MAYBE_ERLANG=""
AC_SUBST([MAYBE_ERLANG]) AC_SUBST([MAYBE_ERLANG])
if test "$have_lua" = "yes" ; then MAYBE_LUA="lua" ; else MAYBE_LUA="" ; fi if test "$have_lua" = "yes" ; then MAYBE_LUA="lua" ; else MAYBE_LUA="" ; fi
AC_SUBST([MAYBE_LUA]) AC_SUBST([MAYBE_LUA])
if test "$have_rs" = "yes" ; then MAYBE_RS="rs" ; else MAYBE_RS="" ; fi
AC_SUBST([MAYBE_RS])
if test "$have_dotnetcore" = "yes" ; then MAYBE_DOTNETCORE="netcore" ; else MAYBE_DOTNETCORE="" ; fi
AC_SUBST([MAYBE_DOTNETCORE])
AC_OUTPUT AC_OUTPUT
@ -841,99 +905,42 @@ AC_OUTPUT
echo echo
echo "$PACKAGE $VERSION" echo "$PACKAGE $VERSION"
echo echo
echo "Building Plugin Support ...... : $have_plugin"
echo "Building C++ Library ......... : $have_cpp"
echo "Building C (GLib) Library .... : $have_c_glib" echo "Building C (GLib) Library .... : $have_c_glib"
echo "Building Java Library ........ : $have_java" echo "Building C# (Mono) Library ... : $have_csharp"
echo "Building C# Library .......... : $have_csharp" echo "Building C++ Library ......... : $have_cpp"
echo "Building Python Library ...... : $have_python" echo "Building D Library ........... : $have_d"
echo "Building Ruby Library ........ : $have_ruby"
echo "Building Haxe Library ........ : $have_haxe"
echo "Building Haskell Library ..... : $have_haskell"
echo "Building Perl Library ........ : $have_perl"
echo "Building PHP Library ......... : $have_php"
echo "Building Dart Library ........ : $have_dart" echo "Building Dart Library ........ : $have_dart"
echo "Building dotnetcore Library .. : $have_dotnetcore"
echo "Building Erlang Library ...... : $have_erlang" echo "Building Erlang Library ...... : $have_erlang"
echo "Building Go Library .......... : $have_go" echo "Building Go Library .......... : $have_go"
echo "Building D Library ........... : $have_d" echo "Building Haskell Library ..... : $have_haskell"
echo "Building NodeJS Library ...... : $have_nodejs" echo "Building Haxe Library ........ : $have_haxe"
echo "Building Java Library ........ : $have_java"
echo "Building Lua Library ......... : $have_lua" echo "Building Lua Library ......... : $have_lua"
echo "Building NodeJS Library ...... : $have_nodejs"
echo "Building Perl Library ........ : $have_perl"
echo "Building PHP Library ......... : $have_php"
echo "Building Plugin Support ...... : $have_plugin"
echo "Building Python Library ...... : $have_python"
echo "Building Py3 Library ......... : $have_py3"
echo "Building Ruby Library ........ : $have_ruby"
echo "Building Rust Library ........ : $have_rs"
if test "$have_cpp" = "yes" ; then
echo
echo "C++ Library:"
echo " Build TZlibTransport ...... : $have_zlib"
echo " Build TNonblockingServer .. : $have_libevent"
echo " Build TQTcpServer (Qt4) .... : $have_qt"
echo " Build TQTcpServer (Qt5) .... : $have_qt5"
fi
if test "$have_java" = "yes" ; then
echo
echo "Java Library:"
echo " Using javac ............... : $JAVAC"
echo " Using java ................ : $JAVA"
echo " Using ant ................. : $ANT"
fi
if test "$have_csharp" = "yes" ; then if test "$have_csharp" = "yes" ; then
echo echo
echo "C# Library:" echo "C# Library:"
echo " Using .NET 3.5 ............ : $net_3_5" echo " Using .NET 3.5 ............ : $net_3_5"
echo " Using mono version ........ : $($MCS --version | head -1)"
fi fi
if test "$have_python" = "yes" ; then if test "$have_cpp" = "yes" ; then
echo echo
echo "Python Library:" echo "C++ Library:"
echo " Using Python .............. : $PYTHON" echo " C++ compiler .............. : $CXX"
if test "$have_py3" = "yes" ; then echo " Build TZlibTransport ...... : $have_zlib"
echo " Using Python3 ............. : $PYTHON3" echo " Build TNonblockingServer .. : $have_libevent"
fi echo " Build TQTcpServer (Qt4) ... : $have_qt"
if test "$have_trial" = "yes"; then echo " Build TQTcpServer (Qt5) ... : $have_qt5"
echo " Using trial ............... : $TRIAL" echo " C++ compiler version ...... : $($CXX --version | head -1)"
fi
fi
if test "$have_php" = "yes" ; then
echo
echo "PHP Library:"
echo " Using php-config .......... : $PHP_CONFIG"
fi
if test "$have_dart" = "yes" ; then
echo
echo "Dart Library:"
echo " Using Dart ................ : $DART"
echo " Using Pub ................. : $DARTPUB"
fi
if test "$have_ruby" = "yes" ; then
echo
echo "Ruby Library:"
echo " Using Ruby ................ : $RUBY"
fi
if test "$have_haskell" = "yes" ; then
echo
echo "Haskell Library:"
echo " Using Haskell ............. : $RUNHASKELL"
echo " Using Cabal ............... : $CABAL"
fi
if test "$have_haxe" = "yes" ; then
echo
echo "Haxe Library:"
echo " Using Haxe ................ : $HAXE"
echo " Using Haxe version ........ : $HAXE_VERSION"
fi
if test "$have_perl" = "yes" ; then
echo
echo "Perl Library:"
echo " Using Perl ................ : $PERL"
fi
if test "$have_erlang" = "yes" ; then
echo
echo "Erlang Library:"
echo " Using erlc ................ : $ERLC"
echo " Using rebar ............... : $REBAR"
fi
if test "$have_go" = "yes" ; then
echo
echo "Go Library:"
echo " Using Go................... : $GO"
echo " Using Go version........... : $($GO version)"
fi fi
if test "$have_d" = "yes" ; then if test "$have_d" = "yes" ; then
echo echo
@ -941,6 +948,61 @@ if test "$have_d" = "yes" ; then
echo " Using D Compiler .......... : $DMD" echo " Using D Compiler .......... : $DMD"
echo " Building D libevent tests . : $with_d_event_tests" echo " Building D libevent tests . : $with_d_event_tests"
echo " Building D SSL tests ...... : $with_d_ssl_tests" echo " Building D SSL tests ...... : $with_d_ssl_tests"
echo " Using D version ........... : $($DMD --version | head -1)"
fi
if test "$have_dart" = "yes" ; then
echo
echo "Dart Library:"
echo " Using Dart ................ : $DART"
echo " Using Pub ................. : $DARTPUB"
echo " Using Dart version ........ : $($DART --version 2>&1)"
fi
if test "$have_dotnetcore" = "yes" ; then
echo
echo ".NET Core Library:"
echo " Using .NET Core ........... : $DOTNETCORE"
echo " Using .NET Core version ... : $DOTNETCORE_VERSION"
fi
if test "$have_erlang" = "yes" ; then
echo
echo "Erlang Library:"
echo " Using erlc ................ : $ERLC"
echo " Using rebar ............... : $REBAR"
echo " Using erlc version ........ : $($ERL -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell | tr -d '\"')"
fi
if test "$have_go" = "yes" ; then
echo
echo "Go Library:"
echo " Using Go................... : $GO"
echo " Using Go version........... : $($GO version)"
fi
if test "$have_haskell" = "yes" ; then
echo
echo "Haskell Library:"
echo " Using Cabal ............... : $CABAL"
echo " Using Haskell ............. : $RUNHASKELL"
echo " Using Haskell version ..... : $($RUNHASKELL --version)"
fi
if test "$have_haxe" = "yes" ; then
echo
echo "Haxe Library:"
echo " Using Haxe ................ : $HAXE"
echo " Using Haxe version ........ : $HAXE_VERSION"
fi
if test "$have_java" = "yes" ; then
echo
echo "Java Library:"
echo " Using ant ................. : $ANT"
echo " Using java ................ : $JAVA"
echo " Using javac ............... : $JAVAC"
echo " Using ant version ......... : $($ANT -version 2>&1)"
echo " Using java version ........ : $($JAVA -version 2>&1 | grep 'version ')"
fi
if test "$have_lua" = "yes" ; then
echo
echo "Lua Library:"
echo " Using Lua ................. : $LUA"
echo " Using Lua version.......... : $($LUA -v)"
fi fi
if test "$have_nodejs" = "yes" ; then if test "$have_nodejs" = "yes" ; then
echo echo
@ -948,12 +1010,46 @@ if test "$have_nodejs" = "yes" ; then
echo " Using NodeJS .............. : $NODEJS" echo " Using NodeJS .............. : $NODEJS"
echo " Using NodeJS version....... : $($NODEJS --version)" echo " Using NodeJS version....... : $($NODEJS --version)"
fi fi
if test "$have_lua" = "yes" ; then if test "$have_perl" = "yes" ; then
echo echo
echo "Lua Library:" echo "Perl Library:"
echo " Using Lua .............. : $LUA" echo " Using Perl ................ : $PERL"
echo " Using Perl version ........ : $($PERL -v | grep 'version ')"
fi
if test "$have_php" = "yes" ; then
echo
echo "PHP Library:"
echo " Using php-config .......... : $PHP_CONFIG"
echo " Using php version ......... : $($PHP --version | head -1)"
fi
if test "$have_python" = "yes" ; then
echo
echo "Python Library:"
echo " Using Python .............. : $PYTHON"
echo " Using Python version ...... : $($PYTHON --version 2>&1)"
if test "$have_py3" = "yes" ; then
echo " Using Python3 ............. : $PYTHON3"
echo " Using Python3 version ..... : $($PYTHON3 --version)"
fi
if test "$have_trial" = "yes"; then
echo " Using trial ............... : $TRIAL"
fi
fi
if test "$have_ruby" = "yes" ; then
echo
echo "Ruby Library:"
echo " Using Ruby ................ : $RUBY"
echo " Using Ruby version ........ : $($RUBY --version)"
fi
if test "$have_rs" = "yes" ; then
echo
echo "Rust Library:"
echo " Using Cargo................ : $CARGO"
echo " Using rustc................ : $RUSTC"
echo " Using Rust version......... : $($RUSTC --version)"
fi fi
echo echo
echo "If something is missing that you think should be present," echo "If something is missing that you think should be present,"
echo "please skim the output of configure to find the missing" echo "please skim the output of configure to find the missing"
echo "component. Details are present in config.log." echo "component. Details are present in config.log."
echo

View file

@ -1,8 +1,8 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"?> <?xml-stylesheet type="text/xsl"?>
<rdf:RDF xml:lang="en" <rdf:RDF xml:lang="en"
xmlns="http://usefulinc.com/ns/doap#" xmlns="http://usefulinc.com/ns/doap#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:asfext="http://projects.apache.org/ns/asfext#" xmlns:asfext="http://projects.apache.org/ns/asfext#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"> xmlns:foaf="http://xmlns.com/foaf/0.1/">
<!-- <!--
@ -12,9 +12,9 @@
The ASF licenses this file to You under the Apache License, Version 2.0 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 not use this file except in compliance with
the License. You may obtain a copy of the License at the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View file

@ -71,6 +71,10 @@ if WITH_DART
SUBDIRS += dart SUBDIRS += dart
endif endif
if WITH_DOTNETCORE
SUBDIRS += netcore
endif
if WITH_GO if WITH_GO
SUBDIRS += go SUBDIRS += go
endif endif
@ -89,6 +93,10 @@ if WITH_LUA
SUBDIRS += lua SUBDIRS += lua
endif endif
if WITH_RS
SUBDIRS += rs
endif
# All of the libs that don't use Automake need to go in here # All of the libs that don't use Automake need to go in here
# so they will end up in our release tarballs. # so they will end up in our release tarballs.
EXTRA_DIST = \ EXTRA_DIST = \

View file

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

View file

@ -30,11 +30,22 @@ const (
PROTOCOL_ERROR = 7 PROTOCOL_ERROR = 7
) )
var defaultApplicationExceptionMessage = map[int32]string{
UNKNOWN_APPLICATION_EXCEPTION: "unknown application exception",
UNKNOWN_METHOD: "unknown method",
INVALID_MESSAGE_TYPE_EXCEPTION: "invalid message type",
WRONG_METHOD_NAME: "wrong method name",
BAD_SEQUENCE_ID: "bad sequence ID",
MISSING_RESULT: "missing result",
INTERNAL_ERROR: "unknown internal error",
PROTOCOL_ERROR: "unknown protocol error",
}
// Application level Thrift exception // Application level Thrift exception
type TApplicationException interface { type TApplicationException interface {
TException TException
TypeId() int32 TypeId() int32
Read(iprot TProtocol) (TApplicationException, error) Read(iprot TProtocol) error
Write(oprot TProtocol) error Write(oprot TProtocol) error
} }
@ -44,7 +55,10 @@ type tApplicationException struct {
} }
func (e tApplicationException) Error() string { func (e tApplicationException) Error() string {
return e.message if e.message != "" {
return e.message
}
return defaultApplicationExceptionMessage[e.type_]
} }
func NewTApplicationException(type_ int32, message string) TApplicationException { func NewTApplicationException(type_ int32, message string) TApplicationException {
@ -55,10 +69,11 @@ func (p *tApplicationException) TypeId() int32 {
return p.type_ return p.type_
} }
func (p *tApplicationException) Read(iprot TProtocol) (TApplicationException, error) { func (p *tApplicationException) Read(iprot TProtocol) error {
// TODO: this should really be generated by the compiler
_, err := iprot.ReadStructBegin() _, err := iprot.ReadStructBegin()
if err != nil { if err != nil {
return nil, err return err
} }
message := "" message := ""
@ -67,7 +82,7 @@ func (p *tApplicationException) Read(iprot TProtocol) (TApplicationException, er
for { for {
_, ttype, id, err := iprot.ReadFieldBegin() _, ttype, id, err := iprot.ReadFieldBegin()
if err != nil { if err != nil {
return nil, err return err
} }
if ttype == STOP { if ttype == STOP {
break break
@ -76,33 +91,40 @@ func (p *tApplicationException) Read(iprot TProtocol) (TApplicationException, er
case 1: case 1:
if ttype == STRING { if ttype == STRING {
if message, err = iprot.ReadString(); err != nil { if message, err = iprot.ReadString(); err != nil {
return nil, err return err
} }
} else { } else {
if err = SkipDefaultDepth(iprot, ttype); err != nil { if err = SkipDefaultDepth(iprot, ttype); err != nil {
return nil, err return err
} }
} }
case 2: case 2:
if ttype == I32 { if ttype == I32 {
if type_, err = iprot.ReadI32(); err != nil { if type_, err = iprot.ReadI32(); err != nil {
return nil, err return err
} }
} else { } else {
if err = SkipDefaultDepth(iprot, ttype); err != nil { if err = SkipDefaultDepth(iprot, ttype); err != nil {
return nil, err return err
} }
} }
default: default:
if err = SkipDefaultDepth(iprot, ttype); err != nil { if err = SkipDefaultDepth(iprot, ttype); err != nil {
return nil, err return err
} }
} }
if err = iprot.ReadFieldEnd(); err != nil { if err = iprot.ReadFieldEnd(); err != nil {
return nil, err return err
} }
} }
return NewTApplicationException(type_, message), iprot.ReadStructEnd() if err := iprot.ReadStructEnd(); err != nil {
return err
}
p.message = message
p.type_ = type_
return nil
} }
func (p *tApplicationException) Write(oprot TProtocol) (err error) { func (p *tApplicationException) Write(oprot TProtocol) (err error) {

View file

@ -25,7 +25,7 @@ import (
func TestTApplicationException(t *testing.T) { func TestTApplicationException(t *testing.T) {
exc := NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "") exc := NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "")
if exc.Error() != "" { if exc.Error() != defaultApplicationExceptionMessage[UNKNOWN_APPLICATION_EXCEPTION] {
t.Fatalf("Expected empty string for exception but found '%s'", exc.Error()) t.Fatalf("Expected empty string for exception but found '%s'", exc.Error())
} }
if exc.TypeId() != UNKNOWN_APPLICATION_EXCEPTION { if exc.TypeId() != UNKNOWN_APPLICATION_EXCEPTION {

View file

@ -32,8 +32,8 @@ type TBufferedTransport struct {
tp TTransport tp TTransport
} }
func (p *TBufferedTransportFactory) GetTransport(trans TTransport) TTransport { func (p *TBufferedTransportFactory) GetTransport(trans TTransport) (TTransport, error) {
return NewTBufferedTransport(trans, p.size) return NewTBufferedTransport(trans, p.size), nil
} }
func NewTBufferedTransportFactory(bufferSize int) *TBufferedTransportFactory { func NewTBufferedTransportFactory(bufferSize int) *TBufferedTransportFactory {

View file

@ -0,0 +1,78 @@
package thrift
import "fmt"
type TStandardClient struct {
seqId int32
iprot, oprot TProtocol
}
// TStandardClient implements TClient, and uses the standard message format for Thrift.
// It is not safe for concurrent use.
func NewTStandardClient(inputProtocol, outputProtocol TProtocol) *TStandardClient {
return &TStandardClient{
iprot: inputProtocol,
oprot: outputProtocol,
}
}
func (p *TStandardClient) Send(oprot TProtocol, seqId int32, method string, args TStruct) error {
if err := oprot.WriteMessageBegin(method, CALL, seqId); err != nil {
return err
}
if err := args.Write(oprot); err != nil {
return err
}
if err := oprot.WriteMessageEnd(); err != nil {
return err
}
return oprot.Flush()
}
func (p *TStandardClient) Recv(iprot TProtocol, seqId int32, method string, result TStruct) error {
rMethod, rTypeId, rSeqId, err := iprot.ReadMessageBegin()
if err != nil {
return err
}
if method != rMethod {
return NewTApplicationException(WRONG_METHOD_NAME, fmt.Sprintf("%s: wrong method name", method))
} else if seqId != rSeqId {
return NewTApplicationException(BAD_SEQUENCE_ID, fmt.Sprintf("%s: out of order sequence response", method))
} else if rTypeId == EXCEPTION {
var exception tApplicationException
if err := exception.Read(iprot); err != nil {
return err
}
if err := iprot.ReadMessageEnd(); err != nil {
return err
}
return &exception
} else if rTypeId != REPLY {
return NewTApplicationException(INVALID_MESSAGE_TYPE_EXCEPTION, fmt.Sprintf("%s: invalid message type", method))
}
if err := result.Read(iprot); err != nil {
return err
}
return iprot.ReadMessageEnd()
}
func (p *TStandardClient) call(method string, args, result TStruct) error {
p.seqId++
seqId := p.seqId
if err := p.Send(p.oprot, seqId, method, args); err != nil {
return err
}
// method is oneway
if result == nil {
return nil
}
return p.Recv(p.iprot, seqId, method, result)
}

View file

@ -0,0 +1,13 @@
// +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

@ -0,0 +1,13 @@
// +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

@ -0,0 +1,32 @@
// +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"
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

@ -0,0 +1,32 @@
// +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

@ -26,28 +26,28 @@ import (
func TestReadWriteCompactProtocol(t *testing.T) { func TestReadWriteCompactProtocol(t *testing.T) {
ReadWriteProtocolTest(t, NewTCompactProtocolFactory()) ReadWriteProtocolTest(t, NewTCompactProtocolFactory())
transports := []TTransport{ transports := []TTransport{
NewTMemoryBuffer(), NewTMemoryBuffer(),
NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 16384))), NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 16384))),
NewTFramedTransport(NewTMemoryBuffer()), NewTFramedTransport(NewTMemoryBuffer()),
} }
for _, trans := range transports { for _, trans := range transports {
p := NewTCompactProtocol(trans); p := NewTCompactProtocol(trans)
ReadWriteBool(t, p, trans); ReadWriteBool(t, p, trans)
p = NewTCompactProtocol(trans); p = NewTCompactProtocol(trans)
ReadWriteByte(t, p, trans); ReadWriteByte(t, p, trans)
p = NewTCompactProtocol(trans); p = NewTCompactProtocol(trans)
ReadWriteI16(t, p, trans); ReadWriteI16(t, p, trans)
p = NewTCompactProtocol(trans); p = NewTCompactProtocol(trans)
ReadWriteI32(t, p, trans); ReadWriteI32(t, p, trans)
p = NewTCompactProtocol(trans); p = NewTCompactProtocol(trans)
ReadWriteI64(t, p, trans); ReadWriteI64(t, p, trans)
p = NewTCompactProtocol(trans); p = NewTCompactProtocol(trans)
ReadWriteDouble(t, p, trans); ReadWriteDouble(t, p, trans)
p = NewTCompactProtocol(trans); p = NewTCompactProtocol(trans)
ReadWriteString(t, p, trans); ReadWriteString(t, p, trans)
p = NewTCompactProtocol(trans); p = NewTCompactProtocol(trans)
ReadWriteBinary(t, p, trans); ReadWriteBinary(t, p, trans)
trans.Close(); trans.Close()
} }
} }

View file

@ -48,11 +48,15 @@ func NewTFramedTransportFactory(factory TTransportFactory) TTransportFactory {
} }
func NewTFramedTransportFactoryMaxLength(factory TTransportFactory, maxLength uint32) TTransportFactory { func NewTFramedTransportFactoryMaxLength(factory TTransportFactory, maxLength uint32) TTransportFactory {
return &tFramedTransportFactory{factory: factory, maxLength: maxLength} return &tFramedTransportFactory{factory: factory, maxLength: maxLength}
} }
func (p *tFramedTransportFactory) GetTransport(base TTransport) TTransport { func (p *tFramedTransportFactory) GetTransport(base TTransport) (TTransport, error) {
return NewTFramedTransportMaxLength(p.factory.GetTransport(base), p.maxLength) tt, err := p.factory.GetTransport(base)
if err != nil {
return nil, err
}
return NewTFramedTransportMaxLength(tt, p.maxLength), nil
} }
func NewTFramedTransport(transport TTransport) *TFramedTransport { func NewTFramedTransport(transport TTransport) *TFramedTransport {
@ -137,11 +141,13 @@ func (p *TFramedTransport) Flush() error {
binary.BigEndian.PutUint32(buf, uint32(size)) binary.BigEndian.PutUint32(buf, uint32(size))
_, err := p.transport.Write(buf) _, err := p.transport.Write(buf)
if err != nil { if err != nil {
p.buf.Truncate(0)
return NewTTransportExceptionFromError(err) return NewTTransportExceptionFromError(err)
} }
if size > 0 { if size > 0 {
if n, err := p.buf.WriteTo(p.transport); err != nil { if n, err := p.buf.WriteTo(p.transport); err != nil {
print("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.Error(), "\n") print("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.Error(), "\n")
p.buf.Truncate(0)
return NewTTransportExceptionFromError(err) return NewTTransportExceptionFromError(err)
} }
} }
@ -164,4 +170,3 @@ func (p *TFramedTransport) readFrameHeader() (uint32, error) {
func (p *TFramedTransport) RemainingBytes() (num_bytes uint64) { func (p *TFramedTransport) RemainingBytes() (num_bytes uint64) {
return uint64(p.frameSize) return uint64(p.frameSize)
} }

26
vendor/github.com/apache/thrift/lib/go/thrift/go17.go generated vendored Normal file
View file

@ -0,0 +1,26 @@
// +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"
var defaultCtx = context.Background()

View file

@ -46,27 +46,16 @@ type THttpClient struct {
type THttpClientTransportFactory struct { type THttpClientTransportFactory struct {
options THttpClientOptions options THttpClientOptions
url string url string
isPost bool
} }
func (p *THttpClientTransportFactory) GetTransport(trans TTransport) TTransport { func (p *THttpClientTransportFactory) GetTransport(trans TTransport) (TTransport, error) {
if trans != nil { if trans != nil {
t, ok := trans.(*THttpClient) t, ok := trans.(*THttpClient)
if ok && t.url != nil { if ok && t.url != nil {
if t.requestBuffer != nil { return NewTHttpClientWithOptions(t.url.String(), p.options)
t2, _ := NewTHttpPostClientWithOptions(t.url.String(), p.options)
return t2
}
t2, _ := NewTHttpClientWithOptions(t.url.String(), p.options)
return t2
} }
} }
if p.isPost { return NewTHttpClientWithOptions(p.url, p.options)
s, _ := NewTHttpPostClientWithOptions(p.url, p.options)
return s
}
s, _ := NewTHttpClientWithOptions(p.url, p.options)
return s
} }
type THttpClientOptions struct { type THttpClientOptions struct {
@ -79,39 +68,10 @@ func NewTHttpClientTransportFactory(url string) *THttpClientTransportFactory {
} }
func NewTHttpClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory { func NewTHttpClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory {
return &THttpClientTransportFactory{url: url, isPost: false, options: options} return &THttpClientTransportFactory{url: url, options: options}
}
func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory {
return NewTHttpPostClientTransportFactoryWithOptions(url, THttpClientOptions{})
}
func NewTHttpPostClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory {
return &THttpClientTransportFactory{url: url, isPost: true, options: options}
} }
func NewTHttpClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) { func NewTHttpClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) {
parsedURL, err := url.Parse(urlstr)
if err != nil {
return nil, err
}
response, err := http.Get(urlstr)
if err != nil {
return nil, err
}
client := options.Client
if client == nil {
client = DefaultHttpClient
}
httpHeader := map[string][]string{"Content-Type": []string{"application/x-thrift"}}
return &THttpClient{client: client, response: response, url: parsedURL, header: httpHeader}, nil
}
func NewTHttpClient(urlstr string) (TTransport, error) {
return NewTHttpClientWithOptions(urlstr, THttpClientOptions{})
}
func NewTHttpPostClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) {
parsedURL, err := url.Parse(urlstr) parsedURL, err := url.Parse(urlstr)
if err != nil { if err != nil {
return nil, err return nil, err
@ -121,12 +81,12 @@ func NewTHttpPostClientWithOptions(urlstr string, options THttpClientOptions) (T
if client == nil { if client == nil {
client = DefaultHttpClient client = DefaultHttpClient
} }
httpHeader := map[string][]string{"Content-Type": []string{"application/x-thrift"}} httpHeader := map[string][]string{"Content-Type": {"application/x-thrift"}}
return &THttpClient{client: client, url: parsedURL, requestBuffer: bytes.NewBuffer(buf), header: httpHeader}, nil return &THttpClient{client: client, url: parsedURL, requestBuffer: bytes.NewBuffer(buf), header: httpHeader}, nil
} }
func NewTHttpPostClient(urlstr string) (TTransport, error) { func NewTHttpClient(urlstr string) (TTransport, error) {
return NewTHttpPostClientWithOptions(urlstr, THttpClientOptions{}) return NewTHttpClientWithOptions(urlstr, THttpClientOptions{})
} }
// Set the HTTP Header for this specific Thrift Transport // Set the HTTP Header for this specific Thrift Transport
@ -256,3 +216,23 @@ func (p *THttpClient) RemainingBytes() (num_bytes uint64) {
const maxSize = ^uint64(0) const maxSize = ^uint64(0)
return maxSize // the thruth is, we just don't know unless framed is used return maxSize // the thruth is, we just don't know unless framed is used
} }
// Deprecated: Use NewTHttpClientTransportFactory instead.
func NewTHttpPostClientTransportFactory(url string) *THttpClientTransportFactory {
return NewTHttpClientTransportFactoryWithOptions(url, THttpClientOptions{})
}
// Deprecated: Use NewTHttpClientTransportFactoryWithOptions instead.
func NewTHttpPostClientTransportFactoryWithOptions(url string, options THttpClientOptions) *THttpClientTransportFactory {
return NewTHttpClientTransportFactoryWithOptions(url, options)
}
// Deprecated: Use NewTHttpClientWithOptions instead.
func NewTHttpPostClientWithOptions(urlstr string, options THttpClientOptions) (TTransport, error) {
return NewTHttpClientWithOptions(urlstr, options)
}
// Deprecated: Use NewTHttpClient instead.
func NewTHttpPostClient(urlstr string) (TTransport, error) {
return NewTHttpClientWithOptions(urlstr, THttpClientOptions{})
}

View file

@ -19,16 +19,33 @@
package thrift package thrift
import "net/http" import (
"compress/gzip"
// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function "io"
func NewThriftHandlerFunc(processor TProcessor, "net/http"
inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { "strings"
)
// gz transparently compresses the HTTP response if the client supports it.
func gz(handler http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/x-thrift") if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
handler(w, r)
transport := NewStreamTransport(r.Body, w) return
processor.Process(inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) }
w.Header().Set("Content-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
handler(gzw, r)
} }
} }
type gzipResponseWriter struct {
io.Writer
http.ResponseWriter
}
func (w gzipResponseWriter) Write(b []byte) (int, error) {
return w.Writer.Write(b)
}

View file

@ -0,0 +1,38 @@
// +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

@ -0,0 +1,40 @@
// +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

@ -38,38 +38,38 @@ type StreamTransportFactory struct {
isReadWriter bool isReadWriter bool
} }
func (p *StreamTransportFactory) GetTransport(trans TTransport) TTransport { func (p *StreamTransportFactory) GetTransport(trans TTransport) (TTransport, error) {
if trans != nil { if trans != nil {
t, ok := trans.(*StreamTransport) t, ok := trans.(*StreamTransport)
if ok { if ok {
if t.isReadWriter { if t.isReadWriter {
return NewStreamTransportRW(t.Reader.(io.ReadWriter)) return NewStreamTransportRW(t.Reader.(io.ReadWriter)), nil
} }
if t.Reader != nil && t.Writer != nil { if t.Reader != nil && t.Writer != nil {
return NewStreamTransport(t.Reader, t.Writer) return NewStreamTransport(t.Reader, t.Writer), nil
} }
if t.Reader != nil && t.Writer == nil { if t.Reader != nil && t.Writer == nil {
return NewStreamTransportR(t.Reader) return NewStreamTransportR(t.Reader), nil
} }
if t.Reader == nil && t.Writer != nil { if t.Reader == nil && t.Writer != nil {
return NewStreamTransportW(t.Writer) return NewStreamTransportW(t.Writer), nil
} }
return &StreamTransport{} return &StreamTransport{}, nil
} }
} }
if p.isReadWriter { if p.isReadWriter {
return NewStreamTransportRW(p.Reader.(io.ReadWriter)) return NewStreamTransportRW(p.Reader.(io.ReadWriter)), nil
} }
if p.Reader != nil && p.Writer != nil { if p.Reader != nil && p.Writer != nil {
return NewStreamTransport(p.Reader, p.Writer) return NewStreamTransport(p.Reader, p.Writer), nil
} }
if p.Reader != nil && p.Writer == nil { if p.Reader != nil && p.Writer == nil {
return NewStreamTransportR(p.Reader) return NewStreamTransportR(p.Reader), nil
} }
if p.Reader == nil && p.Writer != nil { if p.Reader == nil && p.Writer != nil {
return NewStreamTransportW(p.Writer) return NewStreamTransportW(p.Writer), nil
} }
return &StreamTransport{} return &StreamTransport{}, nil
} }
func NewStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *StreamTransportFactory { func NewStreamTransportFactory(reader io.Reader, writer io.Writer, isReadWriter bool) *StreamTransportFactory {
@ -209,6 +209,5 @@ func (p *StreamTransport) WriteString(s string) (n int, err error) {
func (p *StreamTransport) RemainingBytes() (num_bytes uint64) { func (p *StreamTransport) RemainingBytes() (num_bytes uint64) {
const maxSize = ^uint64(0) const maxSize = ^uint64(0)
return maxSize // the thruth is, we just don't know unless framed is used return maxSize // the thruth is, we just don't know unless framed is used
} }

View file

@ -36,7 +36,10 @@ var tfv = []TTransportFactory{
} }
func BenchmarkBinaryBool_0(b *testing.B) { func BenchmarkBinaryBool_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBool(b, p, trans) ReadWriteBool(b, p, trans)
@ -44,7 +47,10 @@ func BenchmarkBinaryBool_0(b *testing.B) {
} }
func BenchmarkBinaryByte_0(b *testing.B) { func BenchmarkBinaryByte_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteByte(b, p, trans) ReadWriteByte(b, p, trans)
@ -52,7 +58,10 @@ func BenchmarkBinaryByte_0(b *testing.B) {
} }
func BenchmarkBinaryI16_0(b *testing.B) { func BenchmarkBinaryI16_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI16(b, p, trans) ReadWriteI16(b, p, trans)
@ -60,35 +69,50 @@ func BenchmarkBinaryI16_0(b *testing.B) {
} }
func BenchmarkBinaryI32_0(b *testing.B) { func BenchmarkBinaryI32_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI32(b, p, trans) ReadWriteI32(b, p, trans)
} }
} }
func BenchmarkBinaryI64_0(b *testing.B) { func BenchmarkBinaryI64_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI64(b, p, trans) ReadWriteI64(b, p, trans)
} }
} }
func BenchmarkBinaryDouble_0(b *testing.B) { func BenchmarkBinaryDouble_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteDouble(b, p, trans) ReadWriteDouble(b, p, trans)
} }
} }
func BenchmarkBinaryString_0(b *testing.B) { func BenchmarkBinaryString_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteString(b, p, trans) ReadWriteString(b, p, trans)
} }
} }
func BenchmarkBinaryBinary_0(b *testing.B) { func BenchmarkBinaryBinary_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBinary(b, p, trans) ReadWriteBinary(b, p, trans)
@ -96,7 +120,10 @@ func BenchmarkBinaryBinary_0(b *testing.B) {
} }
func BenchmarkBinaryBool_1(b *testing.B) { func BenchmarkBinaryBool_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBool(b, p, trans) ReadWriteBool(b, p, trans)
@ -104,7 +131,10 @@ func BenchmarkBinaryBool_1(b *testing.B) {
} }
func BenchmarkBinaryByte_1(b *testing.B) { func BenchmarkBinaryByte_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteByte(b, p, trans) ReadWriteByte(b, p, trans)
@ -112,7 +142,10 @@ func BenchmarkBinaryByte_1(b *testing.B) {
} }
func BenchmarkBinaryI16_1(b *testing.B) { func BenchmarkBinaryI16_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI16(b, p, trans) ReadWriteI16(b, p, trans)
@ -120,35 +153,50 @@ func BenchmarkBinaryI16_1(b *testing.B) {
} }
func BenchmarkBinaryI32_1(b *testing.B) { func BenchmarkBinaryI32_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI32(b, p, trans) ReadWriteI32(b, p, trans)
} }
} }
func BenchmarkBinaryI64_1(b *testing.B) { func BenchmarkBinaryI64_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI64(b, p, trans) ReadWriteI64(b, p, trans)
} }
} }
func BenchmarkBinaryDouble_1(b *testing.B) { func BenchmarkBinaryDouble_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteDouble(b, p, trans) ReadWriteDouble(b, p, trans)
} }
} }
func BenchmarkBinaryString_1(b *testing.B) { func BenchmarkBinaryString_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteString(b, p, trans) ReadWriteString(b, p, trans)
} }
} }
func BenchmarkBinaryBinary_1(b *testing.B) { func BenchmarkBinaryBinary_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBinary(b, p, trans) ReadWriteBinary(b, p, trans)
@ -156,7 +204,10 @@ func BenchmarkBinaryBinary_1(b *testing.B) {
} }
func BenchmarkBinaryBool_2(b *testing.B) { func BenchmarkBinaryBool_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBool(b, p, trans) ReadWriteBool(b, p, trans)
@ -164,7 +215,10 @@ func BenchmarkBinaryBool_2(b *testing.B) {
} }
func BenchmarkBinaryByte_2(b *testing.B) { func BenchmarkBinaryByte_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteByte(b, p, trans) ReadWriteByte(b, p, trans)
@ -172,7 +226,10 @@ func BenchmarkBinaryByte_2(b *testing.B) {
} }
func BenchmarkBinaryI16_2(b *testing.B) { func BenchmarkBinaryI16_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI16(b, p, trans) ReadWriteI16(b, p, trans)
@ -180,35 +237,50 @@ func BenchmarkBinaryI16_2(b *testing.B) {
} }
func BenchmarkBinaryI32_2(b *testing.B) { func BenchmarkBinaryI32_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI32(b, p, trans) ReadWriteI32(b, p, trans)
} }
} }
func BenchmarkBinaryI64_2(b *testing.B) { func BenchmarkBinaryI64_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI64(b, p, trans) ReadWriteI64(b, p, trans)
} }
} }
func BenchmarkBinaryDouble_2(b *testing.B) { func BenchmarkBinaryDouble_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteDouble(b, p, trans) ReadWriteDouble(b, p, trans)
} }
} }
func BenchmarkBinaryString_2(b *testing.B) { func BenchmarkBinaryString_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteString(b, p, trans) ReadWriteString(b, p, trans)
} }
} }
func BenchmarkBinaryBinary_2(b *testing.B) { func BenchmarkBinaryBinary_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := binaryProtoF.GetProtocol(trans) p := binaryProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBinary(b, p, trans) ReadWriteBinary(b, p, trans)
@ -216,7 +288,10 @@ func BenchmarkBinaryBinary_2(b *testing.B) {
} }
func BenchmarkCompactBool_0(b *testing.B) { func BenchmarkCompactBool_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBool(b, p, trans) ReadWriteBool(b, p, trans)
@ -224,7 +299,10 @@ func BenchmarkCompactBool_0(b *testing.B) {
} }
func BenchmarkCompactByte_0(b *testing.B) { func BenchmarkCompactByte_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteByte(b, p, trans) ReadWriteByte(b, p, trans)
@ -232,7 +310,10 @@ func BenchmarkCompactByte_0(b *testing.B) {
} }
func BenchmarkCompactI16_0(b *testing.B) { func BenchmarkCompactI16_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI16(b, p, trans) ReadWriteI16(b, p, trans)
@ -240,35 +321,50 @@ func BenchmarkCompactI16_0(b *testing.B) {
} }
func BenchmarkCompactI32_0(b *testing.B) { func BenchmarkCompactI32_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI32(b, p, trans) ReadWriteI32(b, p, trans)
} }
} }
func BenchmarkCompactI64_0(b *testing.B) { func BenchmarkCompactI64_0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI64(b, p, trans) ReadWriteI64(b, p, trans)
} }
} }
func BenchmarkCompactDouble0(b *testing.B) { func BenchmarkCompactDouble0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteDouble(b, p, trans) ReadWriteDouble(b, p, trans)
} }
} }
func BenchmarkCompactString0(b *testing.B) { func BenchmarkCompactString0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteString(b, p, trans) ReadWriteString(b, p, trans)
} }
} }
func BenchmarkCompactBinary0(b *testing.B) { func BenchmarkCompactBinary0(b *testing.B) {
trans := tfv[0].GetTransport(nil) trans, err := tfv[0].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBinary(b, p, trans) ReadWriteBinary(b, p, trans)
@ -276,7 +372,10 @@ func BenchmarkCompactBinary0(b *testing.B) {
} }
func BenchmarkCompactBool_1(b *testing.B) { func BenchmarkCompactBool_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBool(b, p, trans) ReadWriteBool(b, p, trans)
@ -284,7 +383,10 @@ func BenchmarkCompactBool_1(b *testing.B) {
} }
func BenchmarkCompactByte_1(b *testing.B) { func BenchmarkCompactByte_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteByte(b, p, trans) ReadWriteByte(b, p, trans)
@ -292,7 +394,10 @@ func BenchmarkCompactByte_1(b *testing.B) {
} }
func BenchmarkCompactI16_1(b *testing.B) { func BenchmarkCompactI16_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI16(b, p, trans) ReadWriteI16(b, p, trans)
@ -300,35 +405,50 @@ func BenchmarkCompactI16_1(b *testing.B) {
} }
func BenchmarkCompactI32_1(b *testing.B) { func BenchmarkCompactI32_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI32(b, p, trans) ReadWriteI32(b, p, trans)
} }
} }
func BenchmarkCompactI64_1(b *testing.B) { func BenchmarkCompactI64_1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI64(b, p, trans) ReadWriteI64(b, p, trans)
} }
} }
func BenchmarkCompactDouble1(b *testing.B) { func BenchmarkCompactDouble1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteDouble(b, p, trans) ReadWriteDouble(b, p, trans)
} }
} }
func BenchmarkCompactString1(b *testing.B) { func BenchmarkCompactString1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteString(b, p, trans) ReadWriteString(b, p, trans)
} }
} }
func BenchmarkCompactBinary1(b *testing.B) { func BenchmarkCompactBinary1(b *testing.B) {
trans := tfv[1].GetTransport(nil) trans, err := tfv[1].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBinary(b, p, trans) ReadWriteBinary(b, p, trans)
@ -336,7 +456,10 @@ func BenchmarkCompactBinary1(b *testing.B) {
} }
func BenchmarkCompactBool_2(b *testing.B) { func BenchmarkCompactBool_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBool(b, p, trans) ReadWriteBool(b, p, trans)
@ -344,7 +467,10 @@ func BenchmarkCompactBool_2(b *testing.B) {
} }
func BenchmarkCompactByte_2(b *testing.B) { func BenchmarkCompactByte_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteByte(b, p, trans) ReadWriteByte(b, p, trans)
@ -352,7 +478,10 @@ func BenchmarkCompactByte_2(b *testing.B) {
} }
func BenchmarkCompactI16_2(b *testing.B) { func BenchmarkCompactI16_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI16(b, p, trans) ReadWriteI16(b, p, trans)
@ -360,35 +489,50 @@ func BenchmarkCompactI16_2(b *testing.B) {
} }
func BenchmarkCompactI32_2(b *testing.B) { func BenchmarkCompactI32_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI32(b, p, trans) ReadWriteI32(b, p, trans)
} }
} }
func BenchmarkCompactI64_2(b *testing.B) { func BenchmarkCompactI64_2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteI64(b, p, trans) ReadWriteI64(b, p, trans)
} }
} }
func BenchmarkCompactDouble2(b *testing.B) { func BenchmarkCompactDouble2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteDouble(b, p, trans) ReadWriteDouble(b, p, trans)
} }
} }
func BenchmarkCompactString2(b *testing.B) { func BenchmarkCompactString2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteString(b, p, trans) ReadWriteString(b, p, trans)
} }
} }
func BenchmarkCompactBinary2(b *testing.B) { func BenchmarkCompactBinary2(b *testing.B) {
trans := tfv[2].GetTransport(nil) trans, err := tfv[2].GetTransport(nil)
if err != nil {
b.Fatal(err)
}
p := compactProtoF.GetProtocol(trans) p := compactProtoF.GetProtocol(trans)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ReadWriteBinary(b, p, trans) ReadWriteBinary(b, p, trans)

View file

@ -33,14 +33,14 @@ type TMemoryBufferTransportFactory struct {
size int size int
} }
func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) TTransport { func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) (TTransport, error) {
if trans != nil { if trans != nil {
t, ok := trans.(*TMemoryBuffer) t, ok := trans.(*TMemoryBuffer)
if ok && t.size > 0 { if ok && t.size > 0 {
return NewTMemoryBufferLen(t.size) return NewTMemoryBufferLen(t.size), nil
} }
} }
return NewTMemoryBufferLen(p.size) return NewTMemoryBufferLen(p.size), nil
} }
func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory { func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory {

View file

@ -19,11 +19,6 @@
package thrift package thrift
import (
"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,
@ -127,31 +122,6 @@ func (t *TMultiplexedProcessor) RegisterProcessor(name string, processor TProces
t.serviceProcessorMap[name] = processor t.serviceProcessorMap[name] = processor
} }
func (t *TMultiplexedProcessor) Process(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(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(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

@ -0,0 +1,53 @@
// +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

@ -0,0 +1,54 @@
// +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

@ -0,0 +1,26 @@
// +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,3 +1,5 @@
// +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,12 +21,14 @@
package thrift package thrift
import "golang.org/x/net/context"
// A processor is a generic object which operates upon an input stream and // A processor is a generic object which operates upon an input stream and
// writes to some output stream. // writes to some output stream.
type TProcessor interface { type TProcessor interface {
Process(in, out TProtocol) (bool, TException) Process(ctx context.Context, in, out TProtocol) (bool, TException)
} }
type TProcessorFunction interface { type TProcessorFunction interface {
Process(seqId int32, in, out TProtocol) (bool, TException) Process(ctx context.Context, seqId int32, in, out TProtocol) (bool, TException)
} }

View file

@ -0,0 +1,34 @@
// +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

@ -21,6 +21,7 @@ package thrift
import ( import (
"errors" "errors"
"fmt"
) )
const ( const (
@ -88,9 +89,9 @@ func SkipDefaultDepth(prot TProtocol, typeId TType) (err error) {
// Skips over the next data element from the provided input TProtocol object. // Skips over the next data element from the provided input TProtocol object.
func Skip(self TProtocol, fieldType TType, maxDepth int) (err error) { func Skip(self TProtocol, fieldType TType, maxDepth int) (err error) {
if maxDepth <= 0 { if maxDepth <= 0 {
return NewTProtocolExceptionWithType( DEPTH_LIMIT, errors.New("Depth limit exceeded")) return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded"))
} }
switch fieldType { switch fieldType {
@ -170,6 +171,8 @@ func Skip(self TProtocol, fieldType TType, maxDepth int) (err error) {
} }
} }
return self.ReadListEnd() return self.ReadListEnd()
default:
return NewTProtocolExceptionWithType(INVALID_DATA, errors.New(fmt.Sprintf("Unknown data type %d", fieldType)))
} }
return nil return nil
} }

View file

@ -60,7 +60,7 @@ func NewTProtocolException(err error) TProtocolException {
if err == nil { if err == nil {
return nil return nil
} }
if e,ok := err.(TProtocolException); ok { if e, ok := err.(TProtocolException); ok {
return e return e
} }
if _, ok := err.(base64.CorruptInputError); ok { if _, ok := err.(base64.CorruptInputError); ok {
@ -75,4 +75,3 @@ func NewTProtocolExceptionWithType(errType int, err error) TProtocolException {
} }
return &tProtocolException{errType, err.Error()} return &tProtocolException{errType, err.Error()}
} }

View file

@ -123,55 +123,91 @@ func ReadWriteProtocolTest(t *testing.T, protocolFactory TProtocolFactory) {
NewTHttpPostClientTransportFactory("http://" + addr.String()), NewTHttpPostClientTransportFactory("http://" + addr.String()),
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteBool(t, p, trans) ReadWriteBool(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteByte(t, p, trans) ReadWriteByte(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteI16(t, p, trans) ReadWriteI16(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteI32(t, p, trans) ReadWriteI32(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteI64(t, p, trans) ReadWriteI64(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteDouble(t, p, trans) ReadWriteDouble(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteString(t, p, trans) ReadWriteString(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteBinary(t, p, trans) ReadWriteBinary(t, p, trans)
trans.Close() trans.Close()
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
p := protocolFactory.GetProtocol(trans) p := protocolFactory.GetProtocol(trans)
ReadWriteI64(t, p, trans) ReadWriteI64(t, p, trans)
ReadWriteDouble(t, p, trans) ReadWriteDouble(t, p, trans)

View file

@ -66,4 +66,3 @@ func writeByte(w io.Writer, c byte) error {
_, err := w.Write(v[0:1]) _, err := w.Write(v[0:1])
return err return err
} }

View file

@ -37,7 +37,11 @@ func TestEnsureTransportsAreRich(t *testing.T) {
NewTHttpPostClientTransportFactory("http://127.0.0.1"), NewTHttpPostClientTransportFactory("http://127.0.0.1"),
} }
for _, tf := range transports { for _, tf := range transports {
trans := tf.GetTransport(nil) trans, err := tf.GetTransport(nil)
if err != nil {
t.Error(err)
continue
}
_, ok := trans.(TRichTransport) _, ok := trans.(TRichTransport)
if !ok { if !ok {
t.Errorf("Transport %s does not implement TRichTransport interface", reflect.ValueOf(trans)) t.Errorf("Transport %s does not implement TRichTransport interface", reflect.ValueOf(trans))

View file

@ -598,7 +598,7 @@ func (p *MyTestStruct) writeField11(oprot TProtocol) (err error) {
if err := oprot.WriteSetBegin(STRING, len(p.StringSet)); err != nil { if err := oprot.WriteSetBegin(STRING, len(p.StringSet)); err != nil {
return PrependError("error writing set begin: ", err) return PrependError("error writing set begin: ", err)
} }
for v, _ := range p.StringSet { for v := range p.StringSet {
if err := oprot.WriteString(string(v)); err != nil { if err := oprot.WriteString(string(v)); err != nil {
return PrependError(fmt.Sprintf("%T. (0) field write error: ", p), err) return PrependError(fmt.Sprintf("%T. (0) field write error: ", p), err)
} }

View file

@ -47,7 +47,14 @@ func NewTServerSocketTimeout(listenAddr string, clientTimeout time.Duration) (*T
return &TServerSocket{addr: addr, clientTimeout: clientTimeout}, nil return &TServerSocket{addr: addr, clientTimeout: clientTimeout}, nil
} }
// Creates a TServerSocket from a net.Addr
func NewTServerSocketFromAddrTimeout(addr net.Addr, clientTimeout time.Duration) *TServerSocket {
return &TServerSocket{addr: addr, clientTimeout: clientTimeout}
}
func (p *TServerSocket) Listen() error { func (p *TServerSocket) Listen() error {
p.mu.Lock()
defer p.mu.Unlock()
if p.IsListening() { if p.IsListening() {
return nil return nil
} }
@ -67,10 +74,13 @@ func (p *TServerSocket) Accept() (TTransport, error) {
if interrupted { if interrupted {
return nil, errTransportInterrupted return nil, errTransportInterrupted
} }
if p.listener == nil {
listener := p.listener
if listener == nil {
return nil, NewTTransportException(NOT_OPEN, "No underlying server socket") return nil, NewTTransportException(NOT_OPEN, "No underlying server socket")
} }
conn, err := p.listener.Accept()
conn, err := listener.Accept()
if err != nil { if err != nil {
return nil, NewTTransportExceptionFromError(err) return nil, NewTTransportExceptionFromError(err)
} }
@ -84,6 +94,8 @@ func (p *TServerSocket) IsListening() bool {
// Connects the socket, creating a new socket object if necessary. // Connects the socket, creating a new socket object if necessary.
func (p *TServerSocket) Open() error { func (p *TServerSocket) Open() error {
p.mu.Lock()
defer p.mu.Unlock()
if p.IsListening() { if p.IsListening() {
return NewTTransportException(ALREADY_OPEN, "Server socket already open") return NewTTransportException(ALREADY_OPEN, "Server socket already open")
} }
@ -114,9 +126,9 @@ func (p *TServerSocket) Close() error {
func (p *TServerSocket) Interrupt() error { func (p *TServerSocket) Interrupt() error {
p.mu.Lock() p.mu.Lock()
defer p.mu.Unlock()
p.interrupted = true p.interrupted = true
p.Close() p.Close()
p.mu.Unlock()
return nil return nil
} }

View file

@ -41,6 +41,16 @@ func TestSocketIsntListeningAfterInterrupt(t *testing.T) {
} }
} }
func TestSocketConcurrency(t *testing.T) {
host := "127.0.0.1"
port := 9090
addr := fmt.Sprintf("%s:%d", host, port)
socket := CreateServerSocket(t, addr)
go func() { socket.Listen() }()
go func() { socket.Interrupt() }()
}
func CreateServerSocket(t *testing.T, addr string) *TServerSocket { func CreateServerSocket(t *testing.T, addr string) *TServerSocket {
socket, err := NewTServerSocket(addr) socket, err := NewTServerSocket(addr)
if err != nil { if err != nil {

View file

@ -23,11 +23,18 @@ import (
"log" "log"
"runtime/debug" "runtime/debug"
"sync" "sync"
"sync/atomic"
) )
// Simple, non-concurrent server for testing. /*
* This is not a typical TSimpleServer as it is not blocked after accept a socket.
* It is more like a TThreadedServer that can handle different connections in different goroutines.
* This will work if golang user implements a conn-pool like thing in client side.
*/
type TSimpleServer struct { type TSimpleServer struct {
quit chan struct{} closed int32
wg sync.WaitGroup
mu sync.Mutex
processorFactory TProcessorFactory processorFactory TProcessorFactory
serverTransport TServerTransport serverTransport TServerTransport
@ -87,7 +94,6 @@ func NewTSimpleServerFactory6(processorFactory TProcessorFactory, serverTranspor
outputTransportFactory: outputTransportFactory, outputTransportFactory: outputTransportFactory,
inputProtocolFactory: inputProtocolFactory, inputProtocolFactory: inputProtocolFactory,
outputProtocolFactory: outputProtocolFactory, outputProtocolFactory: outputProtocolFactory,
quit: make(chan struct{}, 1),
} }
} }
@ -122,21 +128,23 @@ func (p *TSimpleServer) Listen() error {
func (p *TSimpleServer) AcceptLoop() error { func (p *TSimpleServer) AcceptLoop() error {
for { for {
client, err := p.serverTransport.Accept() client, err := p.serverTransport.Accept()
p.mu.Lock()
if atomic.LoadInt32(&p.closed) != 0 {
return nil
}
if err != nil { if err != nil {
select {
case <-p.quit:
return nil
default:
}
return err return err
} }
if client != nil { if client != nil {
p.wg.Add(1)
go func() { go func() {
defer p.wg.Done()
if err := p.processRequests(client); err != nil { if err := p.processRequests(client); err != nil {
log.Println("error processing request:", err) log.Println("error processing request:", err)
} }
}() }()
} }
p.mu.Unlock()
} }
} }
@ -149,21 +157,28 @@ func (p *TSimpleServer) Serve() error {
return nil return nil
} }
var once sync.Once
func (p *TSimpleServer) Stop() error { func (p *TSimpleServer) Stop() error {
q := func() { p.mu.Lock()
p.quit <- struct{}{} defer p.mu.Unlock()
p.serverTransport.Interrupt() if atomic.LoadInt32(&p.closed) != 0 {
return nil
} }
once.Do(q) atomic.StoreInt32(&p.closed, 1)
p.serverTransport.Interrupt()
p.wg.Wait()
return nil return nil
} }
func (p *TSimpleServer) processRequests(client TTransport) error { func (p *TSimpleServer) processRequests(client TTransport) error {
processor := p.processorFactory.GetProcessor(client) processor := p.processorFactory.GetProcessor(client)
inputTransport := p.inputTransportFactory.GetTransport(client) inputTransport, err := p.inputTransportFactory.GetTransport(client)
outputTransport := p.outputTransportFactory.GetTransport(client) if err != nil {
return err
}
outputTransport, err := p.outputTransportFactory.GetTransport(client)
if err != nil {
return err
}
inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport) inputProtocol := p.inputProtocolFactory.GetProtocol(inputTransport)
outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport) outputProtocol := p.outputProtocolFactory.GetProtocol(outputTransport)
defer func() { defer func() {
@ -171,6 +186,7 @@ func (p *TSimpleServer) processRequests(client TTransport) error {
log.Printf("panic in processor: %s: %s", e, debug.Stack()) log.Printf("panic in processor: %s: %s", e, debug.Stack())
} }
}() }()
if inputTransport != nil { if inputTransport != nil {
defer inputTransport.Close() defer inputTransport.Close()
} }
@ -178,17 +194,20 @@ func (p *TSimpleServer) processRequests(client TTransport) error {
defer outputTransport.Close() defer outputTransport.Close()
} }
for { for {
ok, err := processor.Process(inputProtocol, outputProtocol) if atomic.LoadInt32(&p.closed) != 0 {
return nil
}
ok, err := processor.Process(defaultCtx, inputProtocol, outputProtocol)
if err, ok := err.(TTransportException); ok && err.TypeId() == END_OF_FILE { if err, ok := err.(TTransportException); ok && err.TypeId() == END_OF_FILE {
return nil return nil
} else if err != nil { } else if err != nil {
log.Printf("error processing request: %s", err)
return err return err
} }
if err, ok := err.(TApplicationException); ok && err.TypeId() == UNKNOWN_METHOD { if err, ok := err.(TApplicationException); ok && err.TypeId() == UNKNOWN_METHOD {
continue continue
} }
if !ok { if !ok {
break break
} }
} }

View file

@ -0,0 +1,127 @@
/*
* 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 (
"testing"
"time"
)
type mockServerTransport struct {
ListenFunc func() error
AcceptFunc func() (TTransport, error)
CloseFunc func() error
InterruptFunc func() error
}
func (m *mockServerTransport) Listen() error {
return m.ListenFunc()
}
func (m *mockServerTransport) Accept() (TTransport, error) {
return m.AcceptFunc()
}
func (m *mockServerTransport) Close() error {
return m.CloseFunc()
}
func (m *mockServerTransport) Interrupt() error {
return m.InterruptFunc()
}
type mockTTransport struct {
TTransport
}
func (m *mockTTransport) Close() error {
return nil
}
func TestMultipleStop(t *testing.T) {
proc := &mockProcessor{
ProcessFunc: func(in, out TProtocol) (bool, TException) {
return false, nil
},
}
var interruptCalled bool
c := make(chan struct{})
trans := &mockServerTransport{
ListenFunc: func() error {
return nil
},
AcceptFunc: func() (TTransport, error) {
<-c
return nil, nil
},
CloseFunc: func() error {
c <- struct{}{}
return nil
},
InterruptFunc: func() error {
interruptCalled = true
return nil
},
}
serv := NewTSimpleServer2(proc, trans)
go serv.Serve()
serv.Stop()
if !interruptCalled {
t.Error("first server transport should have been interrupted")
}
serv = NewTSimpleServer2(proc, trans)
interruptCalled = false
go serv.Serve()
serv.Stop()
if !interruptCalled {
t.Error("second server transport should have been interrupted")
}
}
func TestWaitRace(t *testing.T) {
proc := &mockProcessor{
ProcessFunc: func(in, out TProtocol) (bool, TException) {
return false, nil
},
}
trans := &mockServerTransport{
ListenFunc: func() error {
return nil
},
AcceptFunc: func() (TTransport, error) {
return &mockTTransport{}, nil
},
CloseFunc: func() error {
return nil
},
InterruptFunc: func() error {
return nil
},
}
serv := NewTSimpleServer2(proc, trans)
go serv.Serve()
time.Sleep(1)
serv.Stop()
}

View file

@ -161,6 +161,5 @@ func (p *TSocket) Interrupt() error {
func (p *TSocket) RemainingBytes() (num_bytes uint64) { func (p *TSocket) RemainingBytes() (num_bytes uint64) {
const maxSize = ^uint64(0) const maxSize = ^uint64(0)
return maxSize // the thruth is, we just don't know unless framed is used return maxSize // the thruth is, we just don't know unless framed is used
} }

View file

@ -20,9 +20,9 @@
package thrift package thrift
import ( import (
"crypto/tls"
"net" "net"
"time" "time"
"crypto/tls"
) )
type TSSLServerSocket struct { type TSSLServerSocket struct {
@ -38,6 +38,9 @@ func NewTSSLServerSocket(listenAddr string, cfg *tls.Config) (*TSSLServerSocket,
} }
func NewTSSLServerSocketTimeout(listenAddr string, cfg *tls.Config, clientTimeout time.Duration) (*TSSLServerSocket, error) { func NewTSSLServerSocketTimeout(listenAddr string, cfg *tls.Config, clientTimeout time.Duration) (*TSSLServerSocket, error) {
if cfg.MinVersion == 0 {
cfg.MinVersion = tls.VersionTLS10
}
addr, err := net.ResolveTCPAddr("tcp", listenAddr) addr, err := net.ResolveTCPAddr("tcp", listenAddr)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -48,6 +48,9 @@ func NewTSSLSocket(hostPort string, cfg *tls.Config) (*TSSLSocket, error) {
// NewTSSLSocketTimeout creates a net.Conn-backed TTransport, given a host and port // NewTSSLSocketTimeout creates a net.Conn-backed TTransport, given a host and port
// it also accepts a tls Configuration and a timeout as a time.Duration // it also accepts a tls Configuration and a timeout as a time.Duration
func NewTSSLSocketTimeout(hostPort string, cfg *tls.Config, timeout time.Duration) (*TSSLSocket, error) { func NewTSSLSocketTimeout(hostPort string, cfg *tls.Config, timeout time.Duration) (*TSSLSocket, error) {
if cfg.MinVersion == 0 {
cfg.MinVersion = tls.VersionTLS10
}
return &TSSLSocket{hostPort: hostPort, timeout: timeout, cfg: cfg}, nil return &TSSLSocket{hostPort: hostPort, timeout: timeout, cfg: cfg}, nil
} }
@ -87,7 +90,8 @@ func (p *TSSLSocket) Open() error {
// If we have a hostname, we need to pass the hostname to tls.Dial for // If we have a hostname, we need to pass the hostname to tls.Dial for
// certificate hostname checks. // certificate hostname checks.
if p.hostPort != "" { if p.hostPort != "" {
if p.conn, err = tls.Dial("tcp", p.hostPort, p.cfg); err != nil { if p.conn, err = tls.DialWithDialer(&net.Dialer{
Timeout: p.timeout}, "tcp", p.hostPort, p.cfg); err != nil {
return NewTTransportException(NOT_OPEN, err.Error()) return NewTTransportException(NOT_OPEN, err.Error())
} }
} else { } else {
@ -103,7 +107,8 @@ func (p *TSSLSocket) Open() error {
if len(p.addr.String()) == 0 { if len(p.addr.String()) == 0 {
return NewTTransportException(NOT_OPEN, "Cannot open bad address.") return NewTTransportException(NOT_OPEN, "Cannot open bad address.")
} }
if p.conn, err = tls.Dial(p.addr.Network(), p.addr.String(), p.cfg); err != nil { if p.conn, err = tls.DialWithDialer(&net.Dialer{
Timeout: p.timeout}, p.addr.Network(), p.addr.String(), p.cfg); err != nil {
return NewTTransportException(NOT_OPEN, err.Error()) return NewTTransportException(NOT_OPEN, err.Error())
} }
} }
@ -166,6 +171,5 @@ func (p *TSSLSocket) Interrupt() error {
func (p *TSSLSocket) RemainingBytes() (num_bytes uint64) { func (p *TSSLSocket) RemainingBytes() (num_bytes uint64) {
const maxSize = ^uint64(0) const maxSize = ^uint64(0)
return maxSize // the thruth is, we just don't know unless framed is used return maxSize // the thruth is, we just don't know unless framed is used
} }

View file

@ -34,7 +34,6 @@ type ReadSizeProvider interface {
RemainingBytes() (num_bytes uint64) RemainingBytes() (num_bytes uint64)
} }
// Encapsulates the I/O layer // Encapsulates the I/O layer
type TTransport interface { type TTransport interface {
io.ReadWriteCloser io.ReadWriteCloser
@ -52,7 +51,6 @@ type stringWriter interface {
WriteString(s string) (n int, err error) WriteString(s string) (n int, err error)
} }
// This is "enchanced" transport with extra capabilities. You need to use one of these // This is "enchanced" transport with extra capabilities. You need to use one of these
// to construct protocol. // to construct protocol.
// Notably, TSocket does not implement this interface, and it is always a mistake to use // Notably, TSocket does not implement this interface, and it is always a mistake to use
@ -65,4 +63,3 @@ type TRichTransport interface {
Flusher Flusher
ReadSizeProvider ReadSizeProvider
} }

View file

@ -24,14 +24,14 @@ package thrift
// a ServerTransport and then may want to mutate them (i.e. create // a ServerTransport and then may want to mutate them (i.e. create
// a BufferedTransport from the underlying base transport) // a BufferedTransport from the underlying base transport)
type TTransportFactory interface { type TTransportFactory interface {
GetTransport(trans TTransport) TTransport GetTransport(trans TTransport) (TTransport, error)
} }
type tTransportFactory struct{} type tTransportFactory struct{}
// Return a wrapped instance of the base Transport. // Return a wrapped instance of the base Transport.
func (p *tTransportFactory) GetTransport(trans TTransport) TTransport { func (p *tTransportFactory) GetTransport(trans TTransport) (TTransport, error) {
return trans return trans, nil
} }
func NewTTransportFactory() TTransportFactory { func NewTTransportFactory() TTransportFactory {

View file

@ -27,7 +27,8 @@ import (
// TZlibTransportFactory is a factory for TZlibTransport instances // TZlibTransportFactory is a factory for TZlibTransport instances
type TZlibTransportFactory struct { type TZlibTransportFactory struct {
level int level int
factory TTransportFactory
} }
// TZlibTransport is a TTransport implementation that makes use of zlib compression. // TZlibTransport is a TTransport implementation that makes use of zlib compression.
@ -38,14 +39,27 @@ type TZlibTransport struct {
} }
// GetTransport constructs a new instance of NewTZlibTransport // GetTransport constructs a new instance of NewTZlibTransport
func (p *TZlibTransportFactory) GetTransport(trans TTransport) TTransport { func (p *TZlibTransportFactory) GetTransport(trans TTransport) (TTransport, error) {
t, _ := NewTZlibTransport(trans, p.level) if p.factory != nil {
return t // wrap other factory
var err error
trans, err = p.factory.GetTransport(trans)
if err != nil {
return nil, err
}
}
return NewTZlibTransport(trans, p.level)
} }
// NewTZlibTransportFactory constructs a new instance of NewTZlibTransportFactory // NewTZlibTransportFactory constructs a new instance of NewTZlibTransportFactory
func NewTZlibTransportFactory(level int) *TZlibTransportFactory { func NewTZlibTransportFactory(level int) *TZlibTransportFactory {
return &TZlibTransportFactory{level: level} return &TZlibTransportFactory{level: level, factory: nil}
}
// NewTZlibTransportFactory constructs a new instance of TZlibTransportFactory
// as a wrapper over existing transport factory
func NewTZlibTransportFactoryWithFactory(level int, factory TTransportFactory) *TZlibTransportFactory {
return &TZlibTransportFactory{level: level, factory: factory}
} }
// NewTZlibTransport constructs a new instance of TZlibTransport // NewTZlibTransport constructs a new instance of TZlibTransport

View file

@ -31,3 +31,32 @@ func TestZlibTransport(t *testing.T) {
} }
TransportTest(t, trans, trans) TransportTest(t, trans, trans)
} }
type DummyTransportFactory struct{}
func (p *DummyTransportFactory) GetTransport(trans TTransport) (TTransport, error) {
return NewTMemoryBuffer(), nil
}
func TestZlibFactoryTransportWithFactory(t *testing.T) {
factory := NewTZlibTransportFactoryWithFactory(
zlib.BestCompression,
&DummyTransportFactory{},
)
buffer := NewTMemoryBuffer()
trans, err := factory.GetTransport(buffer)
if err != nil {
t.Fatal(err)
}
TransportTest(t, trans, trans)
}
func TestZlibFactoryTransportWithoutFactory(t *testing.T) {
factory := NewTZlibTransportFactoryWithFactory(zlib.BestCompression, nil)
buffer := NewTMemoryBuffer()
trans, err := factory.GetTransport(buffer)
if err != nil {
t.Fatal(err)
}
TransportTest(t, trans, trans)
}

View file

@ -6,7 +6,7 @@
"type": "git", "type": "git",
"url": "https://git-wip-us.apache.org/repos/asf/thrift.git" "url": "https://git-wip-us.apache.org/repos/asf/thrift.git"
}, },
"version": "0.10.0", "version": "1.0.0-dev",
"author": { "author": {
"name": "Apache Thrift Developers", "name": "Apache Thrift Developers",
"email": "dev@thrift.apache.org", "email": "dev@thrift.apache.org",
@ -32,20 +32,24 @@
}, },
"main": "./lib/nodejs/lib/thrift", "main": "./lib/nodejs/lib/thrift",
"engines": { "engines": {
"node": ">= 0.2.4" "node": ">= 4.1.0"
}, },
"dependencies": { "dependencies": {
"node-int64": "~0.3.0", "node-int64": "^0.4.0",
"q": "1.0.x", "q": "^1.5.0",
"ws": "~0.4.32" "ws": ">= 2.2.3"
}, },
"devDependencies": { "devDependencies": {
"buffer-equals": "^1.0.3", "buffer-equals": "^1.0.4",
"commander": "2.1.x", "commander": "^2.11.0",
"connect": "2.7.x", "connect": "^3.6.4",
"istanbul": "^0.3.5", "istanbul": "^0.4.5",
"run-browser": "^2.0.1", "jsdoc": ">=3.5.5",
"tape": "~3.5.0" "minimatch": "^3.0.4",
"phantomjs-prebuilt": "^2.1.7",
"run-browser": "^2.0.2",
"tape": "^4.8.0",
"utf-8-validate": "^3.0.0"
}, },
"scripts": { "scripts": {
"cover": "lib/nodejs/test/testAll.sh COVER", "cover": "lib/nodejs/test/testAll.sh COVER",

View file

@ -16,7 +16,7 @@ development, combines a software stack with a code generation engine to build
services that work efficiently and seamlessly between all major languages. services that work efficiently and seamlessly between all major languages.
# Apache Thrift Version # Apache Thrift Version
sonar.projectVersion=0.10.0 sonar.projectVersion=1.0.0-dev
# use this to set another version string # use this to set another version string
# $ sonar-runner -D sonar.projectVersion=`git rev-parse HEAD` # $ sonar-runner -D sonar.projectVersion=`git rev-parse HEAD`
# set projectDate in combination with projectVersion for imports of old releases # set projectDate in combination with projectVersion for imports of old releases
@ -54,7 +54,7 @@ module1.sonar.projectName=Apache Thrift - Java Library
module1.sonar.projectBaseDir=lib/java module1.sonar.projectBaseDir=lib/java
module1.sonar.sources=src module1.sonar.sources=src
module1.sonar.tests=test module1.sonar.tests=test
module1.sonar.binaries=build/libthrift-0.10.0.jar module1.sonar.binaries=build/libthrift-1.0.0.jar
module1.sonar.libraries=build/lib/*.jar module1.sonar.libraries=build/lib/*.jar
module1.sonar.language=java module1.sonar.language=java

View file

@ -28,6 +28,7 @@ type SimpleSchema struct {
Items *Items `json:"items,omitempty"` Items *Items `json:"items,omitempty"`
CollectionFormat string `json:"collectionFormat,omitempty"` CollectionFormat string `json:"collectionFormat,omitempty"`
Default interface{} `json:"default,omitempty"` Default interface{} `json:"default,omitempty"`
Example interface{} `json:"example,omitempty"`
} }
func (s *SimpleSchema) TypeName() string { func (s *SimpleSchema) TypeName() string {

View file

@ -0,0 +1,14 @@
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/

View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 2017 opentracing-contrib
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,64 @@
# An Observer API for OpenTracing-go Tracers
OTObserver can be used to watch the span events like StartSpan(),
SetOperationName(), SetTag() and Finish(). A need for observers
arose when information (metrics) more than just the latency information was
required for the spans, in the distributed tracers. But, there can be a lot
of metrics in different domains and adding such metrics to any one (client)
tracer breaks cross-platform compatibility. There are various ways to
avoid such issues, however, an observer pattern is cleaner and provides loose
coupling between the packages exporting metrics (on span events) and the
tracer.
This information can be in the form of hardware metrics, RPC metrics,
useful metrics exported out of the kernel or other metrics, profiled for a
span. These additional metrics can help us in getting better Root-cause
analysis. With that being said, its not just for calculation of metrics,
it can be used for anything which needs watching the span events.
## Installation and Usage
The `otobserver` package provides an API to watch span's events and define
callbacks for these events. This API would be a functional option to a
tracer constructor that passes an Observer. 3rd party packages (who want to
watch the span events) should actually implement this observer API.
To do that, first fetch the package using go get :
```
go get -v github.com/opentracing-contrib/go-observer
```
and say :
```go
import "github.com/opentracing-contrib/go-observer"
```
and then, define the required span event callbacks. These registered
callbacks would then be called on span events if an observer is created.
Tracer may allow registering multiple observers. Have a look at the [jaeger's observer](https://github.com/uber/jaeger-client-go/blob/master/observer.go).
With the required setup implemented in the backend tracers, packages
watching the span events need to implement the observer api defining what
they need to do for the observed span events.
## Span events
An observer registered with this api, can observe for the following four
span events :
```go
StartSpan()
SetOperationName()
SetTag()
Finish()
```
### Tradeoffs
As noble as our thoughts might be in fetching additional metrics (other than
latency) for a span using an observer, there are some overhead costs. Not all
observers need to observe all the span events, in which case, we may have
to keep some callback functions empty. In effect, we will still call these
functions, and that will incur unnecessary overhead. To know more about this
and other tradeoffs, see this [discussion](https://github.com/opentracing/opentracing-go/pull/135#discussion_r105497329).

View file

@ -0,0 +1,39 @@
// This project is licensed under the Apache License 2.0, see LICENSE.
package otobserver
import opentracing "github.com/opentracing/opentracing-go"
// Observer can be registered with a Tracer to recieve notifications
// about new Spans. Tracers are not required to support the Observer API.
// The actual registration depends on the implementation, which might look
// like the below e.g :
// observer := myobserver.NewObserver()
// tracer := client.NewTracer(..., client.WithObserver(observer))
//
type Observer interface {
// Create and return a span observer. Called when a span starts.
// If the Observer is not interested in the given span, it must return (nil, false).
// E.g :
// func StartSpan(opName string, opts ...opentracing.StartSpanOption) {
// var sp opentracing.Span
// sso := opentracing.StartSpanOptions{}
// spanObserver, ok := observer.OnStartSpan(span, opName, sso);
// if ok {
// // we have a valid SpanObserver
// }
// ...
// }
OnStartSpan(sp opentracing.Span, operationName string, options opentracing.StartSpanOptions) (SpanObserver, bool)
}
// SpanObserver is created by the Observer and receives notifications about
// other Span events.
type SpanObserver interface {
// Callback called from opentracing.Span.SetOperationName()
OnSetOperationName(operationName string)
// Callback called from opentracing.Span.SetTag()
OnSetTag(key string, value interface{})
// Callback called from opentracing.Span.Finish()
OnFinish(options opentracing.FinishOptions)
}

View file

@ -1,8 +1,8 @@
language: go language: go
go: go:
- 1.7
- 1.8 - 1.8
- 1.9
- tip - tip
install: install:

View file

@ -12,12 +12,15 @@ bench:
.PHONY: lint .PHONY: lint
lint: lint:
# Ignore grep's exit code since no match returns 1. # Ignore grep's exit code since no match returns 1.
-golint ./... | grep --invert-match -E '^.*\.pb\.go' -golint ./... | grep --invert-match -E '^.*\.pb\.go|^thrift'
@ @
@! (golint ./... |grep --invert-match -E '^.*\.pb\.go' | read dummy) @! (golint ./... | grep --invert-match -E '^.*\.pb\.go|^thrift' | read dummy)
.PHONY: vet .PHONY: vet
vet: vet:
go vet ./... go vet ./...
.PHONY: all
all: vet lint test bench
.PHONY: example .PHONY: example

View file

@ -1,431 +0,0 @@
// Autogenerated by Thrift Compiler (0.9.3)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package scribe
import (
"bytes"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
)
// (needed to ensure safety because of naive import list construction.)
var _ = thrift.ZERO
var _ = fmt.Printf
var _ = bytes.Equal
type Scribe interface {
// Parameters:
// - Messages
Log(messages []*LogEntry) (r ResultCode, err error)
}
type ScribeClient struct {
Transport thrift.TTransport
ProtocolFactory thrift.TProtocolFactory
InputProtocol thrift.TProtocol
OutputProtocol thrift.TProtocol
SeqId int32
}
func NewScribeClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *ScribeClient {
return &ScribeClient{Transport: t,
ProtocolFactory: f,
InputProtocol: f.GetProtocol(t),
OutputProtocol: f.GetProtocol(t),
SeqId: 0,
}
}
func NewScribeClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *ScribeClient {
return &ScribeClient{Transport: t,
ProtocolFactory: nil,
InputProtocol: iprot,
OutputProtocol: oprot,
SeqId: 0,
}
}
// Parameters:
// - Messages
func (p *ScribeClient) Log(messages []*LogEntry) (r ResultCode, err error) {
if err = p.sendLog(messages); err != nil {
return
}
return p.recvLog()
}
func (p *ScribeClient) sendLog(messages []*LogEntry) (err error) {
oprot := p.OutputProtocol
if oprot == nil {
oprot = p.ProtocolFactory.GetProtocol(p.Transport)
p.OutputProtocol = oprot
}
p.SeqId++
if err = oprot.WriteMessageBegin("Log", thrift.CALL, p.SeqId); err != nil {
return
}
args := ScribeLogArgs{
Messages: messages,
}
if err = args.Write(oprot); err != nil {
return
}
if err = oprot.WriteMessageEnd(); err != nil {
return
}
return oprot.Flush()
}
func (p *ScribeClient) recvLog() (value ResultCode, err error) {
iprot := p.InputProtocol
if iprot == nil {
iprot = p.ProtocolFactory.GetProtocol(p.Transport)
p.InputProtocol = iprot
}
method, mTypeId, seqId, err := iprot.ReadMessageBegin()
if err != nil {
return
}
if method != "Log" {
err = thrift.NewTApplicationException(thrift.WRONG_METHOD_NAME, "Log failed: wrong method name")
return
}
if p.SeqId != seqId {
err = thrift.NewTApplicationException(thrift.BAD_SEQUENCE_ID, "Log failed: out of sequence response")
return
}
if mTypeId == thrift.EXCEPTION {
error0 := thrift.NewTApplicationException(thrift.UNKNOWN_APPLICATION_EXCEPTION, "Unknown Exception")
var error1 error
error1, err = error0.Read(iprot)
if err != nil {
return
}
if err = iprot.ReadMessageEnd(); err != nil {
return
}
err = error1
return
}
if mTypeId != thrift.REPLY {
err = thrift.NewTApplicationException(thrift.INVALID_MESSAGE_TYPE_EXCEPTION, "Log failed: invalid message type")
return
}
result := ScribeLogResult{}
if err = result.Read(iprot); err != nil {
return
}
if err = iprot.ReadMessageEnd(); err != nil {
return
}
value = result.GetSuccess()
return
}
type ScribeProcessor struct {
processorMap map[string]thrift.TProcessorFunction
handler Scribe
}
func (p *ScribeProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) {
p.processorMap[key] = processor
}
func (p *ScribeProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) {
processor, ok = p.processorMap[key]
return processor, ok
}
func (p *ScribeProcessor) ProcessorMap() map[string]thrift.TProcessorFunction {
return p.processorMap
}
func NewScribeProcessor(handler Scribe) *ScribeProcessor {
self2 := &ScribeProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)}
self2.processorMap["Log"] = &scribeProcessorLog{handler: handler}
return self2
}
func (p *ScribeProcessor) Process(iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
name, _, seqId, err := iprot.ReadMessageBegin()
if err != nil {
return false, err
}
if processor, ok := p.GetProcessorFunction(name); ok {
return processor.Process(seqId, iprot, oprot)
}
iprot.Skip(thrift.STRUCT)
iprot.ReadMessageEnd()
x3 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name)
oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId)
x3.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush()
return false, x3
}
type scribeProcessorLog struct {
handler Scribe
}
func (p *scribeProcessorLog) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
args := ScribeLogArgs{}
if err = args.Read(iprot); err != nil {
iprot.ReadMessageEnd()
x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error())
oprot.WriteMessageBegin("Log", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush()
return false, err
}
iprot.ReadMessageEnd()
result := ScribeLogResult{}
var retval ResultCode
var err2 error
if retval, err2 = p.handler.Log(args.Messages); err2 != nil {
x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Log: "+err2.Error())
oprot.WriteMessageBegin("Log", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush()
return true, err2
} else {
result.Success = &retval
}
if err2 = oprot.WriteMessageBegin("Log", thrift.REPLY, seqId); err2 != nil {
err = err2
}
if err2 = result.Write(oprot); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.Flush(); err == nil && err2 != nil {
err = err2
}
if err != nil {
return
}
return true, err
}
// HELPER FUNCTIONS AND STRUCTURES
// Attributes:
// - Messages
type ScribeLogArgs struct {
Messages []*LogEntry `thrift:"messages,1" json:"messages"`
}
func NewScribeLogArgs() *ScribeLogArgs {
return &ScribeLogArgs{}
}
func (p *ScribeLogArgs) GetMessages() []*LogEntry {
return p.Messages
}
func (p *ScribeLogArgs) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
}
for {
_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
if err != nil {
return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if err := p.readField1(iprot); err != nil {
return err
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
if err := iprot.ReadFieldEnd(); err != nil {
return err
}
}
if err := iprot.ReadStructEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
return nil
}
func (p *ScribeLogArgs) readField1(iprot thrift.TProtocol) error {
_, size, err := iprot.ReadListBegin()
if err != nil {
return thrift.PrependError("error reading list begin: ", err)
}
tSlice := make([]*LogEntry, 0, size)
p.Messages = tSlice
for i := 0; i < size; i++ {
_elem4 := &LogEntry{}
if err := _elem4.Read(iprot); err != nil {
return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem4), err)
}
p.Messages = append(p.Messages, _elem4)
}
if err := iprot.ReadListEnd(); err != nil {
return thrift.PrependError("error reading list end: ", err)
}
return nil
}
func (p *ScribeLogArgs) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("Log_args"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
}
if err := p.writeField1(oprot); err != nil {
return err
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err)
}
if err := oprot.WriteStructEnd(); err != nil {
return thrift.PrependError("write struct stop error: ", err)
}
return nil
}
func (p *ScribeLogArgs) writeField1(oprot thrift.TProtocol) (err error) {
if err := oprot.WriteFieldBegin("messages", thrift.LIST, 1); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:messages: ", p), err)
}
if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Messages)); err != nil {
return thrift.PrependError("error writing list begin: ", err)
}
for _, v := range p.Messages {
if err := v.Write(oprot); err != nil {
return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err)
}
}
if err := oprot.WriteListEnd(); err != nil {
return thrift.PrependError("error writing list end: ", err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 1:messages: ", p), err)
}
return err
}
func (p *ScribeLogArgs) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("ScribeLogArgs(%+v)", *p)
}
// Attributes:
// - Success
type ScribeLogResult struct {
Success *ResultCode `thrift:"success,0" json:"success,omitempty"`
}
func NewScribeLogResult() *ScribeLogResult {
return &ScribeLogResult{}
}
var ScribeLogResult_Success_DEFAULT ResultCode
func (p *ScribeLogResult) GetSuccess() ResultCode {
if !p.IsSetSuccess() {
return ScribeLogResult_Success_DEFAULT
}
return *p.Success
}
func (p *ScribeLogResult) IsSetSuccess() bool {
return p.Success != nil
}
func (p *ScribeLogResult) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
}
for {
_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
if err != nil {
return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 0:
if err := p.readField0(iprot); err != nil {
return err
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
if err := iprot.ReadFieldEnd(); err != nil {
return err
}
}
if err := iprot.ReadStructEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
return nil
}
func (p *ScribeLogResult) readField0(iprot thrift.TProtocol) error {
if v, err := iprot.ReadI32(); err != nil {
return thrift.PrependError("error reading field 0: ", err)
} else {
temp := ResultCode(v)
p.Success = &temp
}
return nil
}
func (p *ScribeLogResult) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("Log_result"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
}
if err := p.writeField0(oprot); err != nil {
return err
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err)
}
if err := oprot.WriteStructEnd(); err != nil {
return thrift.PrependError("write struct stop error: ", err)
}
return nil
}
func (p *ScribeLogResult) writeField0(oprot thrift.TProtocol) (err error) {
if p.IsSetSuccess() {
if err := oprot.WriteFieldBegin("success", thrift.I32, 0); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 0:success: ", p), err)
}
if err := oprot.WriteI32(int32(*p.Success)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.success (0) field write error: ", p), err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 0:success: ", p), err)
}
}
return err
}
func (p *ScribeLogResult) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("ScribeLogResult(%+v)", *p)
}

View file

@ -1,185 +0,0 @@
// Autogenerated by Thrift Compiler (0.9.3)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package scribe
import (
"bytes"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
)
// (needed to ensure safety because of naive import list construction.)
var _ = thrift.ZERO
var _ = fmt.Printf
var _ = bytes.Equal
var GoUnusedProtection__ int
type ResultCode int64
const (
ResultCode_OK ResultCode = 0
ResultCode_TRY_LATER ResultCode = 1
)
func (p ResultCode) String() string {
switch p {
case ResultCode_OK:
return "OK"
case ResultCode_TRY_LATER:
return "TRY_LATER"
}
return "<UNSET>"
}
func ResultCodeFromString(s string) (ResultCode, error) {
switch s {
case "OK":
return ResultCode_OK, nil
case "TRY_LATER":
return ResultCode_TRY_LATER, nil
}
return ResultCode(0), fmt.Errorf("not a valid ResultCode string")
}
func ResultCodePtr(v ResultCode) *ResultCode { return &v }
func (p ResultCode) MarshalText() ([]byte, error) {
return []byte(p.String()), nil
}
func (p *ResultCode) UnmarshalText(text []byte) error {
q, err := ResultCodeFromString(string(text))
if err != nil {
return err
}
*p = q
return nil
}
// Attributes:
// - Category
// - Message
type LogEntry struct {
Category string `thrift:"category,1" json:"category"`
Message string `thrift:"message,2" json:"message"`
}
func NewLogEntry() *LogEntry {
return &LogEntry{}
}
func (p *LogEntry) GetCategory() string {
return p.Category
}
func (p *LogEntry) GetMessage() string {
return p.Message
}
func (p *LogEntry) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
}
for {
_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
if err != nil {
return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if err := p.readField1(iprot); err != nil {
return err
}
case 2:
if err := p.readField2(iprot); err != nil {
return err
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
if err := iprot.ReadFieldEnd(); err != nil {
return err
}
}
if err := iprot.ReadStructEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
return nil
}
func (p *LogEntry) readField1(iprot thrift.TProtocol) error {
if v, err := iprot.ReadString(); err != nil {
return thrift.PrependError("error reading field 1: ", err)
} else {
p.Category = v
}
return nil
}
func (p *LogEntry) readField2(iprot thrift.TProtocol) error {
if v, err := iprot.ReadString(); err != nil {
return thrift.PrependError("error reading field 2: ", err)
} else {
p.Message = v
}
return nil
}
func (p *LogEntry) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("LogEntry"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
}
if err := p.writeField1(oprot); err != nil {
return err
}
if err := p.writeField2(oprot); err != nil {
return err
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err)
}
if err := oprot.WriteStructEnd(); err != nil {
return thrift.PrependError("write struct stop error: ", err)
}
return nil
}
func (p *LogEntry) writeField1(oprot thrift.TProtocol) (err error) {
if err := oprot.WriteFieldBegin("category", thrift.STRING, 1); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:category: ", p), err)
}
if err := oprot.WriteString(string(p.Category)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.category (1) field write error: ", p), err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 1:category: ", p), err)
}
return err
}
func (p *LogEntry) writeField2(oprot thrift.TProtocol) (err error) {
if err := oprot.WriteFieldBegin("message", thrift.STRING, 2); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:message: ", p), err)
}
if err := oprot.WriteString(string(p.Message)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.message (2) field write error: ", p), err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 2:message: ", p), err)
}
return err
}
func (p *LogEntry) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("LogEntry(%+v)", *p)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
dependencies:
override:
- sudo rm -rf /home/ubuntu/.go_workspace/src/github.com/openzipkin
- mkdir -p /home/ubuntu/.go_workspace/src/github.com/openzipkin
- mv /home/ubuntu/zipkin-go-opentracing /home/ubuntu/.go_workspace/src/github.com/openzipkin
- ln -s /home/ubuntu/.go_workspace/src/github.com/openzipkin/zipkin-go-opentracing /home/ubuntu/zipkin-go-opentracing
- go get -u -t -v github.com/openzipkin/zipkin-go-opentracing/...
test:
override:
- make test bench

View file

@ -8,7 +8,7 @@ import (
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
// Default timeout for http request in seconds // Default timeout for http request in seconds
@ -180,7 +180,7 @@ func (c *HTTPCollector) append(span *zipkincore.Span) (newBatchSize int) {
c.batch = append(c.batch, span) c.batch = append(c.batch, span)
if len(c.batch) > c.maxBacklog { if len(c.batch) > c.maxBacklog {
dispose := len(c.batch) - c.maxBacklog dispose := len(c.batch) - c.maxBacklog
c.logger.Log("Backlog too long, disposing spans.", "count", dispose) c.logger.Log("msg", "backlog too long, disposing spans.", "count", dispose)
c.batch = c.batch[dispose:] c.batch = c.batch[dispose:]
} }
newBatchSize = len(c.batch) newBatchSize = len(c.batch)
@ -214,10 +214,16 @@ func (c *HTTPCollector) send() error {
if c.reqCallback != nil { if c.reqCallback != nil {
c.reqCallback(req) c.reqCallback(req)
} }
if _, err = c.client.Do(req); err != nil { resp, err := c.client.Do(req)
if err != nil {
c.logger.Log("err", err.Error()) c.logger.Log("err", err.Error())
return err return err
} }
resp.Body.Close()
// non 2xx code
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
c.logger.Log("err", "HTTP POST span failed", "code", resp.Status)
}
// Remove sent spans from the batch // Remove sent spans from the batch
c.batchMutex.Lock() c.batchMutex.Lock()

View file

@ -11,7 +11,7 @@ import (
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
const ( const (

View file

@ -4,7 +4,7 @@ import (
"github.com/Shopify/sarama" "github.com/Shopify/sarama"
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
// defaultKafkaTopic sets the standard Kafka topic our Collector will publish // defaultKafkaTopic sets the standard Kafka topic our Collector will publish

View file

@ -8,7 +8,7 @@ import (
"github.com/Shopify/sarama" "github.com/Shopify/sarama"
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
type stubProducer struct { type stubProducer struct {

View file

@ -1,6 +1,7 @@
package zipkintracer package zipkintracer
import ( import (
"context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"net" "net"
@ -9,8 +10,8 @@ import (
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/scribe" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/scribe"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
const defaultScribeCategory = "zipkin" const defaultScribeCategory = "zipkin"
@ -198,7 +199,7 @@ func (c *ScribeCollector) send() error {
return err return err
} }
} }
if rc, err := c.client.Log(sendBatch); err != nil { if rc, err := c.client.Log(context.Background(), sendBatch); err != nil {
c.client = nil c.client = nil
_ = c.logger.Log("err", fmt.Sprintf("during Log: %v", err)) _ = c.logger.Log("err", fmt.Sprintf("during Log: %v", err))
return err return err

View file

@ -1,6 +1,7 @@
package zipkintracer package zipkintracer
import ( import (
"context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"math/rand" "math/rand"
@ -11,8 +12,8 @@ import (
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/scribe" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/scribe"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
func TestScribeCollector(t *testing.T) { func TestScribeCollector(t *testing.T) {
@ -143,7 +144,7 @@ func newScribeHandler(t *testing.T) *scribeHandler {
return &scribeHandler{t: t} return &scribeHandler{t: t}
} }
func (h *scribeHandler) Log(messages []*scribe.LogEntry) (scribe.ResultCode, error) { func (h *scribeHandler) Log(ctx context.Context, messages []*scribe.LogEntry) (scribe.ResultCode, error) {
h.Lock() h.Lock()
defer h.Unlock() defer h.Unlock()
for _, m := range messages { for _, m := range messages {

View file

@ -3,7 +3,7 @@ package zipkintracer
import ( import (
"strings" "strings"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
// Collector represents a Zipkin trace collector, which is probably a set of // Collector represents a Zipkin trace collector, which is probably a set of

View file

@ -5,7 +5,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" "github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
var s = makeNewSpan("203.0.113.10:1234", "service1", "avg", 123, 456, 0, true) var s = makeNewSpan("203.0.113.10:1234", "service1", "avg", 123, 456, 0, true)

View file

@ -11,8 +11,9 @@ import (
// not even in number // not even in number
var ErrMissingValue = errors.New("(MISSING)") var ErrMissingValue = errors.New("(MISSING)")
// Logger interface used by this package. // Logger is the fundamental interface for all log operations. Log creates a
// This means that we accept Go kit Log compatible loggers // log event from keyvals, a variadic sequence of alternating keys and values.
// The signature is compatible with the Go kit log package.
type Logger interface { type Logger interface {
Log(keyvals ...interface{}) error Log(keyvals ...interface{}) error
} }

View file

@ -0,0 +1,52 @@
package zipkintracer
import (
otobserver "github.com/opentracing-contrib/go-observer"
opentracing "github.com/opentracing/opentracing-go"
)
// observer is a dispatcher to other observers
type observer struct {
observers []otobserver.Observer
}
// spanObserver is a dispatcher to other span observers
type spanObserver struct {
observers []otobserver.SpanObserver
}
func (o observer) OnStartSpan(sp opentracing.Span, operationName string, options opentracing.StartSpanOptions) (otobserver.SpanObserver, bool) {
var spanObservers []otobserver.SpanObserver
for _, obs := range o.observers {
spanObs, ok := obs.OnStartSpan(sp, operationName, options)
if ok {
if spanObservers == nil {
spanObservers = make([]otobserver.SpanObserver, 0, len(o.observers))
}
spanObservers = append(spanObservers, spanObs)
}
}
if len(spanObservers) == 0 {
return nil, false
}
return spanObserver{observers: spanObservers}, true
}
func (o spanObserver) OnSetOperationName(operationName string) {
for _, obs := range o.observers {
obs.OnSetOperationName(operationName)
}
}
func (o spanObserver) OnSetTag(key string, value interface{}) {
for _, obs := range o.observers {
obs.OnSetTag(key, value)
}
}
func (o spanObserver) OnFinish(options opentracing.FinishOptions) {
for _, obs := range o.observers {
obs.OnFinish(options)
}
}

View file

@ -13,21 +13,21 @@ func TestBoundarySampler(t *testing.T) {
rate float64 rate float64
} }
for input, want := range map[triple]bool{ for input, want := range map[triple]bool{
triple{123, 456, 1.0}: true, {123, 456, 1.0}: true,
triple{123, 456, 999}: true, {123, 456, 999}: true,
triple{123, 456, 0.0}: false, {123, 456, 0.0}: false,
triple{123, 456, -42}: false, {123, 456, -42}: false,
triple{1229998, 0, 0.01}: false, {1229998, 0, 0.01}: false,
triple{1229999, 0, 0.01}: false, {1229999, 0, 0.01}: false,
triple{1230000, 0, 0.01}: true, {1230000, 0, 0.01}: true,
triple{1230001, 0, 0.01}: true, {1230001, 0, 0.01}: true,
triple{1230098, 0, 0.01}: true, {1230098, 0, 0.01}: true,
triple{1230099, 0, 0.01}: true, {1230099, 0, 0.01}: true,
triple{1230100, 0, 0.01}: false, {1230100, 0, 0.01}: false,
triple{1230101, 0, 0.01}: false, {1230101, 0, 0.01}: false,
triple{1, 9999999, 0.01}: false, {1, 9999999, 0.01}: false,
triple{999, 0, 0.99}: true, {999, 0, 0.99}: true,
triple{9999, 0, 0.99}: false, {9999, 0, 0.99}: false,
} { } {
sampler := zipkin.NewBoundarySampler(input.rate, input.salt) sampler := zipkin.NewBoundarySampler(input.rate, input.salt)
if have := sampler(input.id); want != have { if have := sampler(input.id); want != have {

View file

@ -8,7 +8,8 @@ import (
"github.com/opentracing/opentracing-go/ext" "github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log" "github.com/opentracing/opentracing-go/log"
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore" otobserver "github.com/opentracing-contrib/go-observer"
"github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/zipkincore"
) )
// Span provides access to the essential details of the span, for use // Span provides access to the essential details of the span, for use
@ -29,6 +30,7 @@ type Span interface {
type spanImpl struct { type spanImpl struct {
tracer *tracerImpl tracer *tracerImpl
event func(SpanEvent) event func(SpanEvent)
observer otobserver.SpanObserver
sync.Mutex // protects the fields below sync.Mutex // protects the fields below
raw RawSpan raw RawSpan
// The number of logs dropped because of MaxLogsPerSpan. // The number of logs dropped because of MaxLogsPerSpan.
@ -63,6 +65,9 @@ func (s *spanImpl) reset() {
} }
func (s *spanImpl) SetOperationName(operationName string) opentracing.Span { func (s *spanImpl) SetOperationName(operationName string) opentracing.Span {
if s.observer != nil {
s.observer.OnSetOperationName(operationName)
}
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
s.raw.Operation = operationName s.raw.Operation = operationName
@ -75,6 +80,10 @@ func (s *spanImpl) trim() bool {
func (s *spanImpl) SetTag(key string, value interface{}) opentracing.Span { func (s *spanImpl) SetTag(key string, value interface{}) opentracing.Span {
defer s.onTag(key, value) defer s.onTag(key, value)
if s.observer != nil {
s.observer.OnSetTag(key, value)
}
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
if key == string(ext.SamplingPriority) { if key == string(ext.SamplingPriority) {
@ -190,6 +199,10 @@ func (s *spanImpl) FinishWithOptions(opts opentracing.FinishOptions) {
} }
duration := finishTime.Sub(s.raw.Start) duration := finishTime.Sub(s.raw.Start)
if s.observer != nil {
s.observer.OnFinish(opts)
}
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()

View file

@ -1,5 +1,5 @@
#!/usr/bin/env sh #!/usr/bin/env sh
for f in *.thrift ; do for f in *.thrift ; do
thrift -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift $f thrift -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/openzipkin/zipkin-go-opentracing/thrift/gen-go/ $f
done done

View file

@ -0,0 +1,7 @@
// Autogenerated by Thrift Compiler (1.0.0-dev)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package scribe
var GoUnusedProtection__ int;

View file

@ -1,10 +1,12 @@
// Autogenerated by Thrift Compiler (0.9.3) // Autogenerated by Thrift Compiler (1.0.0-dev)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package scribe package scribe
import ( import (
"bytes" "bytes"
"reflect"
"context"
"fmt" "fmt"
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
) )
@ -12,7 +14,11 @@ import (
// (needed to ensure safety because of naive import list construction.) // (needed to ensure safety because of naive import list construction.)
var _ = thrift.ZERO var _ = thrift.ZERO
var _ = fmt.Printf var _ = fmt.Printf
var _ = context.Background
var _ = reflect.DeepEqual
var _ = bytes.Equal var _ = bytes.Equal
func init() { func init() {
} }

View file

@ -0,0 +1,550 @@
// Autogenerated by Thrift Compiler (1.0.0-dev)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package scribe
import (
"bytes"
"reflect"
"database/sql/driver"
"errors"
"context"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
)
// (needed to ensure safety because of naive import list construction.)
var _ = thrift.ZERO
var _ = fmt.Printf
var _ = context.Background
var _ = reflect.DeepEqual
var _ = bytes.Equal
type ResultCode int64
const (
ResultCode_OK ResultCode = 0
ResultCode_TRY_LATER ResultCode = 1
)
func (p ResultCode) String() string {
switch p {
case ResultCode_OK: return "OK"
case ResultCode_TRY_LATER: return "TRY_LATER"
}
return "<UNSET>"
}
func ResultCodeFromString(s string) (ResultCode, error) {
switch s {
case "OK": return ResultCode_OK, nil
case "TRY_LATER": return ResultCode_TRY_LATER, nil
}
return ResultCode(0), fmt.Errorf("not a valid ResultCode string")
}
func ResultCodePtr(v ResultCode) *ResultCode { return &v }
func (p ResultCode) MarshalText() ([]byte, error) {
return []byte(p.String()), nil
}
func (p *ResultCode) UnmarshalText(text []byte) error {
q, err := ResultCodeFromString(string(text))
if (err != nil) {
return err
}
*p = q
return nil
}
func (p *ResultCode) Scan(value interface{}) error {
v, ok := value.(int64)
if !ok {
return errors.New("Scan value is not int64")
}
*p = ResultCode(v)
return nil
}
func (p * ResultCode) Value() (driver.Value, error) {
if p == nil {
return nil, nil
}
return int64(*p), nil
}
// Attributes:
// - Category
// - Message
type LogEntry struct {
Category string `thrift:"category,1" db:"category" json:"category"`
Message string `thrift:"message,2" db:"message" json:"message"`
}
func NewLogEntry() *LogEntry {
return &LogEntry{}
}
func (p *LogEntry) GetCategory() string {
return p.Category
}
func (p *LogEntry) GetMessage() string {
return p.Message
}
func (p *LogEntry) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
}
for {
_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
if err != nil {
return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
}
if fieldTypeId == thrift.STOP { break; }
switch fieldId {
case 1:
if fieldTypeId == thrift.STRING {
if err := p.ReadField1(iprot); err != nil {
return err
}
} else {
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
case 2:
if fieldTypeId == thrift.STRING {
if err := p.ReadField2(iprot); err != nil {
return err
}
} else {
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
if err := iprot.ReadFieldEnd(); err != nil {
return err
}
}
if err := iprot.ReadStructEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
return nil
}
func (p *LogEntry) ReadField1(iprot thrift.TProtocol) error {
if v, err := iprot.ReadString(); err != nil {
return thrift.PrependError("error reading field 1: ", err)
} else {
p.Category = v
}
return nil
}
func (p *LogEntry) ReadField2(iprot thrift.TProtocol) error {
if v, err := iprot.ReadString(); err != nil {
return thrift.PrependError("error reading field 2: ", err)
} else {
p.Message = v
}
return nil
}
func (p *LogEntry) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("LogEntry"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) }
if p != nil {
if err := p.writeField1(oprot); err != nil { return err }
if err := p.writeField2(oprot); err != nil { return err }
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err) }
if err := oprot.WriteStructEnd(); err != nil {
return thrift.PrependError("write struct stop error: ", err) }
return nil
}
func (p *LogEntry) writeField1(oprot thrift.TProtocol) (err error) {
if err := oprot.WriteFieldBegin("category", thrift.STRING, 1); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:category: ", p), err) }
if err := oprot.WriteString(string(p.Category)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.category (1) field write error: ", p), err) }
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 1:category: ", p), err) }
return err
}
func (p *LogEntry) writeField2(oprot thrift.TProtocol) (err error) {
if err := oprot.WriteFieldBegin("message", thrift.STRING, 2); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:message: ", p), err) }
if err := oprot.WriteString(string(p.Message)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.message (2) field write error: ", p), err) }
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 2:message: ", p), err) }
return err
}
func (p *LogEntry) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("LogEntry(%+v)", *p)
}
type Scribe interface {
// Parameters:
// - Messages
Log(ctx context.Context, messages []*LogEntry) (r ResultCode, err error)
}
type ScribeClient struct {
c thrift.TClient
}
// Deprecated: Use NewScribe instead
func NewScribeClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *ScribeClient {
return &ScribeClient{
c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)),
}
}
// Deprecated: Use NewScribe instead
func NewScribeClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *ScribeClient {
return &ScribeClient{
c: thrift.NewTStandardClient(iprot, oprot),
}
}
func NewScribeClient(c thrift.TClient) *ScribeClient {
return &ScribeClient{
c: c,
}
}
// Parameters:
// - Messages
func (p *ScribeClient) Log(ctx context.Context, messages []*LogEntry) (r ResultCode, err error) {
var _args0 ScribeLogArgs
_args0.Messages = messages
var _result1 ScribeLogResult
if err = p.c.Call(ctx, "Log", &_args0, &_result1); err != nil {
return
}
return _result1.GetSuccess(), nil
}
type ScribeProcessor struct {
processorMap map[string]thrift.TProcessorFunction
handler Scribe
}
func (p *ScribeProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) {
p.processorMap[key] = processor
}
func (p *ScribeProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) {
processor, ok = p.processorMap[key]
return processor, ok
}
func (p *ScribeProcessor) ProcessorMap() map[string]thrift.TProcessorFunction {
return p.processorMap
}
func NewScribeProcessor(handler Scribe) *ScribeProcessor {
self2 := &ScribeProcessor{handler:handler, processorMap:make(map[string]thrift.TProcessorFunction)}
self2.processorMap["Log"] = &scribeProcessorLog{handler:handler}
return self2
}
func (p *ScribeProcessor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
name, _, seqId, err := iprot.ReadMessageBegin()
if err != nil { return false, err }
if processor, ok := p.GetProcessorFunction(name); ok {
return processor.Process(ctx, seqId, iprot, oprot)
}
iprot.Skip(thrift.STRUCT)
iprot.ReadMessageEnd()
x3 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function " + name)
oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId)
x3.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush()
return false, x3
}
type scribeProcessorLog struct {
handler Scribe
}
func (p *scribeProcessorLog) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
args := ScribeLogArgs{}
if err = args.Read(iprot); err != nil {
iprot.ReadMessageEnd()
x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error())
oprot.WriteMessageBegin("Log", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush()
return false, err
}
iprot.ReadMessageEnd()
result := ScribeLogResult{}
var retval ResultCode
var err2 error
if retval, err2 = p.handler.Log(ctx, args.Messages); err2 != nil {
x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Log: " + err2.Error())
oprot.WriteMessageBegin("Log", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush()
return true, err2
} else {
result.Success = &retval
}
if err2 = oprot.WriteMessageBegin("Log", thrift.REPLY, seqId); err2 != nil {
err = err2
}
if err2 = result.Write(oprot); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.Flush(); err == nil && err2 != nil {
err = err2
}
if err != nil {
return
}
return true, err
}
// HELPER FUNCTIONS AND STRUCTURES
// Attributes:
// - Messages
type ScribeLogArgs struct {
Messages []*LogEntry `thrift:"messages,1" db:"messages" json:"messages"`
}
func NewScribeLogArgs() *ScribeLogArgs {
return &ScribeLogArgs{}
}
func (p *ScribeLogArgs) GetMessages() []*LogEntry {
return p.Messages
}
func (p *ScribeLogArgs) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
}
for {
_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
if err != nil {
return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
}
if fieldTypeId == thrift.STOP { break; }
switch fieldId {
case 1:
if fieldTypeId == thrift.LIST {
if err := p.ReadField1(iprot); err != nil {
return err
}
} else {
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
if err := iprot.ReadFieldEnd(); err != nil {
return err
}
}
if err := iprot.ReadStructEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
return nil
}
func (p *ScribeLogArgs) ReadField1(iprot thrift.TProtocol) error {
_, size, err := iprot.ReadListBegin()
if err != nil {
return thrift.PrependError("error reading list begin: ", err)
}
tSlice := make([]*LogEntry, 0, size)
p.Messages = tSlice
for i := 0; i < size; i ++ {
_elem4 := &LogEntry{}
if err := _elem4.Read(iprot); err != nil {
return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem4), err)
}
p.Messages = append(p.Messages, _elem4)
}
if err := iprot.ReadListEnd(); err != nil {
return thrift.PrependError("error reading list end: ", err)
}
return nil
}
func (p *ScribeLogArgs) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("Log_args"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) }
if p != nil {
if err := p.writeField1(oprot); err != nil { return err }
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err) }
if err := oprot.WriteStructEnd(); err != nil {
return thrift.PrependError("write struct stop error: ", err) }
return nil
}
func (p *ScribeLogArgs) writeField1(oprot thrift.TProtocol) (err error) {
if err := oprot.WriteFieldBegin("messages", thrift.LIST, 1); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:messages: ", p), err) }
if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Messages)); err != nil {
return thrift.PrependError("error writing list begin: ", err)
}
for _, v := range p.Messages {
if err := v.Write(oprot); err != nil {
return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err)
}
}
if err := oprot.WriteListEnd(); err != nil {
return thrift.PrependError("error writing list end: ", err)
}
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 1:messages: ", p), err) }
return err
}
func (p *ScribeLogArgs) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("ScribeLogArgs(%+v)", *p)
}
// Attributes:
// - Success
type ScribeLogResult struct {
Success *ResultCode `thrift:"success,0" db:"success" json:"success,omitempty"`
}
func NewScribeLogResult() *ScribeLogResult {
return &ScribeLogResult{}
}
var ScribeLogResult_Success_DEFAULT ResultCode
func (p *ScribeLogResult) GetSuccess() ResultCode {
if !p.IsSetSuccess() {
return ScribeLogResult_Success_DEFAULT
}
return *p.Success
}
func (p *ScribeLogResult) IsSetSuccess() bool {
return p.Success != nil
}
func (p *ScribeLogResult) Read(iprot thrift.TProtocol) error {
if _, err := iprot.ReadStructBegin(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err)
}
for {
_, fieldTypeId, fieldId, err := iprot.ReadFieldBegin()
if err != nil {
return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err)
}
if fieldTypeId == thrift.STOP { break; }
switch fieldId {
case 0:
if fieldTypeId == thrift.I32 {
if err := p.ReadField0(iprot); err != nil {
return err
}
} else {
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
default:
if err := iprot.Skip(fieldTypeId); err != nil {
return err
}
}
if err := iprot.ReadFieldEnd(); err != nil {
return err
}
}
if err := iprot.ReadStructEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
return nil
}
func (p *ScribeLogResult) ReadField0(iprot thrift.TProtocol) error {
if v, err := iprot.ReadI32(); err != nil {
return thrift.PrependError("error reading field 0: ", err)
} else {
temp := ResultCode(v)
p.Success = &temp
}
return nil
}
func (p *ScribeLogResult) Write(oprot thrift.TProtocol) error {
if err := oprot.WriteStructBegin("Log_result"); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) }
if p != nil {
if err := p.writeField0(oprot); err != nil { return err }
}
if err := oprot.WriteFieldStop(); err != nil {
return thrift.PrependError("write field stop error: ", err) }
if err := oprot.WriteStructEnd(); err != nil {
return thrift.PrependError("write struct stop error: ", err) }
return nil
}
func (p *ScribeLogResult) writeField0(oprot thrift.TProtocol) (err error) {
if p.IsSetSuccess() {
if err := oprot.WriteFieldBegin("success", thrift.I32, 0); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field begin error 0:success: ", p), err) }
if err := oprot.WriteI32(int32(*p.Success)); err != nil {
return thrift.PrependError(fmt.Sprintf("%T.success (0) field write error: ", p), err) }
if err := oprot.WriteFieldEnd(); err != nil {
return thrift.PrependError(fmt.Sprintf("%T write field end error 0:success: ", p), err) }
}
return err
}
func (p *ScribeLogResult) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("ScribeLogResult(%+v)", *p)
}

View file

@ -0,0 +1,7 @@
// Autogenerated by Thrift Compiler (1.0.0-dev)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package zipkincore
var GoUnusedProtection__ int;

View file

@ -1,10 +1,12 @@
// Autogenerated by Thrift Compiler (0.9.3) // Autogenerated by Thrift Compiler (1.0.0-dev)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
package zipkincore package zipkincore
import ( import (
"bytes" "bytes"
"reflect"
"context"
"fmt" "fmt"
"github.com/apache/thrift/lib/go/thrift" "github.com/apache/thrift/lib/go/thrift"
) )
@ -12,6 +14,8 @@ import (
// (needed to ensure safety because of naive import list construction.) // (needed to ensure safety because of naive import list construction.)
var _ = thrift.ZERO var _ = thrift.ZERO
var _ = fmt.Printf var _ = fmt.Printf
var _ = context.Background
var _ = reflect.DeepEqual
var _ = bytes.Equal var _ = bytes.Equal
const CLIENT_SEND = "cs" const CLIENT_SEND = "cs"
@ -38,3 +42,4 @@ const SERVER_ADDR = "sa"
func init() { func init() {
} }

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,7 @@ import (
opentracing "github.com/opentracing/opentracing-go" opentracing "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext" "github.com/opentracing/opentracing-go/ext"
otobserver "github.com/opentracing-contrib/go-observer"
"github.com/openzipkin/zipkin-go-opentracing/flag" "github.com/openzipkin/zipkin-go-opentracing/flag"
) )
@ -107,6 +108,8 @@ type TracerOptions struct {
// Regardless of this setting, the library will propagate and support both // Regardless of this setting, the library will propagate and support both
// 64 and 128 bit incoming traces from upstream sources. // 64 and 128 bit incoming traces from upstream sources.
traceID128Bit bool traceID128Bit bool
observer otobserver.Observer
} }
// TracerOption allows for functional options. // TracerOption allows for functional options.
@ -231,6 +234,7 @@ func NewTracer(recorder SpanRecorder, options ...TracerOption) (opentracing.Trac
debugMode: false, debugMode: false,
traceID128Bit: false, traceID128Bit: false,
maxLogsPerSpan: 10000, maxLogsPerSpan: 10000,
observer: nil,
} }
for _, o := range options { for _, o := range options {
err := o(opts) err := o(opts)
@ -289,6 +293,11 @@ func (t *tracerImpl) startSpanWithOptions(
// Build the new span. This is the only allocation: We'll return this as // Build the new span. This is the only allocation: We'll return this as
// an opentracing.Span. // an opentracing.Span.
sp := t.getSpan() sp := t.getSpan()
if t.options.observer != nil {
sp.observer, _ = t.options.observer.OnStartSpan(sp, operationName, opts)
}
// Look for a parent in the list of References. // Look for a parent in the list of References.
// //
// TODO: would be nice if basictracer did something with all // TODO: would be nice if basictracer did something with all
@ -379,6 +388,7 @@ func (t *tracerImpl) startSpanInternal(
sp.raw.Start = startTime sp.raw.Start = startTime
sp.raw.Duration = -1 sp.raw.Duration = -1
sp.raw.Tags = tags sp.raw.Tags = tags
if t.options.debugAssertSingleGoroutine { if t.options.debugAssertSingleGoroutine {
sp.SetTag(debugGoroutineIDTag, curGoroutineID()) sp.SetTag(debugGoroutineIDTag, curGoroutineID())
} }
@ -420,3 +430,11 @@ func (t *tracerImpl) Extract(format interface{}, carrier interface{}) (opentraci
func (t *tracerImpl) Options() TracerOptions { func (t *tracerImpl) Options() TracerOptions {
return t.options return t.options
} }
// WithObserver assigns an initialized observer to opts.observer
func WithObserver(observer otobserver.Observer) TracerOption {
return func(opts *TracerOptions) error {
opts.observer = observer
return nil
}
}

View file

@ -1,6 +1,6 @@
package wire package wire
//go:generate protoc --gogofaster_out=$GOPATH/src/github.com/openzipkin/zipkin-go-opentracing/wire wire.proto //go:generate protoc --gogofaster_out=$GOPATH/src wire.proto
// Run `go get github.com/gogo/protobuf/protoc-gen-gogofaster` to install the // Run `go get github.com/gogo/protobuf/protoc-gen-gogofaster` to install the
// gogofaster generator binary. // gogofaster generator binary.

View file

@ -624,24 +624,26 @@ var (
func init() { proto.RegisterFile("wire.proto", fileDescriptorWire) } func init() { proto.RegisterFile("wire.proto", fileDescriptorWire) }
var fileDescriptorWire = []byte{ var fileDescriptorWire = []byte{
// 300 bytes of a gzipped FileDescriptorProto // 325 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xcf, 0x2c, 0x4a, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x91, 0xcf, 0x4a, 0x03, 0x31,
0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xa9, 0xca, 0x2c, 0xc8, 0xce, 0xcc, 0x2b, 0x29, 0x18, 0xc4, 0x4d, 0xab, 0xfd, 0xf3, 0xb5, 0x15, 0x0d, 0x55, 0x57, 0x0f, 0x4b, 0x29, 0x1e, 0x7a,
0x4a, 0x4c, 0x4e, 0x2d, 0x8a, 0x4f, 0xcf, 0xd7, 0x03, 0xc9, 0x29, 0x5d, 0x63, 0xe2, 0xe2, 0x0e, 0xe9, 0x56, 0xec, 0x45, 0xbc, 0x08, 0x05, 0xc1, 0x5e, 0xb7, 0x1e, 0xc4, 0xcb, 0x92, 0xed, 0xc6,
0x01, 0x0b, 0x05, 0x97, 0x24, 0x96, 0xa4, 0x0a, 0x49, 0x72, 0x71, 0x80, 0x55, 0xc4, 0x67, 0xa6, 0x6c, 0x68, 0x9b, 0x84, 0x6c, 0xaa, 0xd4, 0xa7, 0xf0, 0xb1, 0x3c, 0x7a, 0xf2, 0x2c, 0xf5, 0x45,
0x48, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x05, 0xb1, 0x83, 0xf9, 0x9e, 0x29, 0x42, 0xe2, 0x5c, 0xec, 0x24, 0x89, 0x85, 0x82, 0x9e, 0x76, 0x67, 0xe6, 0x1b, 0xf8, 0x31, 0x01, 0x78, 0xe1, 0x9a, 0x46,
0xc5, 0x05, 0x89, 0x79, 0x20, 0x19, 0x26, 0xb0, 0x0c, 0x1b, 0x88, 0xeb, 0x99, 0x22, 0x24, 0xc1, 0x4a, 0x4b, 0x23, 0x71, 0xfb, 0x95, 0xab, 0x19, 0x17, 0x46, 0x93, 0x29, 0xd5, 0x09, 0x93, 0x91,
0xc5, 0x5e, 0x9c, 0x98, 0x5b, 0x90, 0x93, 0x9a, 0x22, 0xc1, 0xac, 0xc0, 0xa8, 0xc1, 0x11, 0x04, 0xcd, 0xba, 0x9f, 0x25, 0x68, 0xdc, 0x3b, 0x6b, 0x62, 0x88, 0xa1, 0xf8, 0x14, 0x6a, 0xee, 0x22,
0xe3, 0x0a, 0x45, 0x70, 0xf1, 0x26, 0x25, 0xa6, 0xa7, 0x27, 0xa6, 0xa7, 0xc6, 0x67, 0x96, 0xa4, 0xe1, 0x59, 0x80, 0x3a, 0xa8, 0x57, 0x89, 0xab, 0x4e, 0x8f, 0x33, 0x7c, 0x02, 0xd5, 0x42, 0x11,
0xe6, 0x16, 0x4b, 0xb0, 0x28, 0x30, 0x6b, 0x70, 0x1b, 0x19, 0xeb, 0x61, 0x73, 0x8b, 0x1e, 0x92, 0x61, 0x93, 0x92, 0x4b, 0x2a, 0x56, 0x8e, 0x33, 0x1c, 0x40, 0xb5, 0x20, 0x0b, 0x35, 0xa7, 0x59,
0x3b, 0xf4, 0x9c, 0x20, 0xda, 0x3c, 0x41, 0xba, 0x5c, 0xf3, 0x4a, 0x8a, 0x2a, 0x83, 0x78, 0x92, 0x50, 0xee, 0xa0, 0x5e, 0x2d, 0xde, 0x48, 0xfc, 0x00, 0xad, 0x94, 0x30, 0x46, 0x18, 0x4d, 0xb8,
0x90, 0x84, 0x84, 0x94, 0xb8, 0x78, 0x61, 0xee, 0x8c, 0xcf, 0xc8, 0x4c, 0xcf, 0x90, 0x10, 0x01, 0xa1, 0x8b, 0x22, 0xd8, 0xed, 0x94, 0x7b, 0x8d, 0xcb, 0x61, 0xf4, 0x1f, 0x4b, 0xb4, 0xc5, 0x11,
0x3b, 0x89, 0x1b, 0xea, 0x58, 0x8f, 0xcc, 0xf4, 0x0c, 0x21, 0x15, 0x2e, 0xbe, 0x82, 0xc4, 0xa2, 0x8d, 0x7c, 0x6d, 0x6c, 0x5b, 0xb7, 0xc2, 0xe8, 0x55, 0xdc, 0x4c, 0xb7, 0x2c, 0xdc, 0x85, 0xd6,
0xd4, 0xbc, 0x92, 0x78, 0x98, 0xbb, 0x45, 0xc1, 0x8a, 0x78, 0x20, 0xa2, 0xc1, 0x10, 0xd7, 0x8b, 0x86, 0x33, 0xc9, 0x39, 0xcb, 0x83, 0xb6, 0x43, 0x6a, 0xfc, 0xc2, 0xde, 0x71, 0x96, 0xe3, 0x73,
0x70, 0xb1, 0xa6, 0xe5, 0x24, 0xa6, 0x17, 0x4b, 0x88, 0x81, 0x25, 0x21, 0x1c, 0x29, 0x7b, 0x2e, 0xd8, 0x57, 0x44, 0x53, 0x61, 0x92, 0x0d, 0xf7, 0x91, 0x3b, 0x6a, 0x7a, 0x77, 0xe2, 0xe9, 0xdb,
0x41, 0x0c, 0x27, 0x08, 0x09, 0x70, 0x31, 0x67, 0xa7, 0x56, 0x82, 0xc3, 0x85, 0x33, 0x08, 0xc4, 0xb0, 0xf7, 0x34, 0x27, 0xac, 0x08, 0x8e, 0x5d, 0xe8, 0xc5, 0xd9, 0x0d, 0x1c, 0xfe, 0x41, 0xc0,
0x04, 0x69, 0x2e, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0x87, 0x08, 0x67, 0x10, 0x84, 0x63, 0xc5, 0x64, 0x07, 0x50, 0x9e, 0xd1, 0x95, 0xdb, 0xa5, 0x1e, 0xdb, 0x5f, 0x5b, 0x7e, 0x26, 0xf3, 0x25, 0x75,
0xc1, 0xe8, 0x24, 0x76, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x8b, 0xd4, 0x63, 0x2f, 0xae, 0x4b, 0x57, 0x68, 0x34, 0x7a, 0x5f, 0x87, 0xe8, 0x63, 0x1d, 0xa2,
0x4e, 0x78, 0x2c, 0xc7, 0x10, 0xc5, 0x02, 0xf2, 0x64, 0x12, 0x1b, 0x38, 0x36, 0x8c, 0x01, 0x01, 0xaf, 0x75, 0x88, 0xde, 0xbe, 0xc3, 0x9d, 0xc7, 0x0b, 0xc6, 0x4d, 0xbe, 0x4c, 0xa3, 0xa9, 0x5c,
0x00, 0x00, 0xff, 0xff, 0xb5, 0x5e, 0x0d, 0x33, 0x9b, 0x01, 0x00, 0x00, 0x0c, 0xa4, 0xa2, 0xc2, 0x6f, 0x30, 0xf0, 0x9f, 0x3e, 0x93, 0x7d, 0x6b, 0x5a, 0x7e, 0x2e, 0xd8,
0xc0, 0x0e, 0x92, 0x56, 0xdc, 0xcb, 0x0d, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x3a, 0xab, 0xcc,
0x6b, 0xc7, 0x01, 0x00, 0x00,
} }

View file

@ -1,6 +1,6 @@
syntax = "proto3"; syntax = "proto3";
package zipkintracer_go.wire; package zipkintracer_go.wire;
option go_package = "wire"; option go_package = "github.com/openzipkin/zipkin-go-opentracing/wire";
message TracerState { message TracerState {
fixed64 trace_id = 1; fixed64 trace_id = 1;

Some files were not shown because too many files have changed in this diff Show more