├── .gitignore ├── .travis.yml ├── AUTHORS ├── BUILD ├── CHANGES ├── INSTALL ├── LICENSE ├── Makefile ├── README ├── README.md ├── TODO ├── WORKSPACE ├── bazel ├── boost.BUILD ├── gtest.BUILD ├── snappy.BUILD └── zlib.BUILD ├── build.sh ├── depends.mk ├── doc ├── image │ ├── arch.png │ ├── basic_arch.png │ ├── flow-controller-result.png │ ├── flow-controller.png │ ├── network-arch.png │ ├── readbuf.png │ ├── rpc-compress.png │ ├── rpc-header.png │ ├── rpc-interface.png │ ├── rpc-thread-1.png │ ├── rpc-thread-2.png │ ├── sofa-interface.png │ ├── stream_layer.png │ ├── timeout-manager.png │ └── writebuf.png └── sofa-pbrpc-document.md ├── image ├── sofa-pbrpc-cpu-profiling.png ├── sofa-pbrpc-feature.jpg ├── sofa-pbrpc-flow-control.jpg ├── sofa-pbrpc-memory-profiling.png ├── sofa-pbrpc-performance-delay.png ├── sofa-pbrpc-performance-qps.png └── sofa-pbrpc-web-monitor.jpg ├── python ├── README ├── compile_proto.sh ├── ez_setup.py ├── sample │ ├── README │ ├── client_http_protobuf.py │ ├── client_sample.py │ ├── compile_proto.sh │ └── echo_service.proto ├── setup.py └── sofa │ ├── __init__.py │ └── pbrpc │ ├── __init__.py │ └── client.py ├── sample ├── compress_sample │ ├── BUILD │ ├── Makefile │ ├── client.cc │ ├── echo_service.proto │ └── server.cc ├── echo │ ├── BUILD │ ├── Makefile │ ├── client_async.cc │ ├── client_http.sh │ ├── client_sync.cc │ ├── echo_service.proto │ └── server.cc ├── mock_sample │ ├── BUILD │ ├── Makefile │ ├── depends.mk │ ├── echo_service.proto │ └── mock_test_sample.cc ├── multi_server_sample │ ├── BUILD │ ├── Makefile │ ├── README │ ├── address_list.txt │ ├── client.cc │ ├── echo_service.proto │ └── server.cc └── timeout_sample │ ├── BUILD │ ├── Makefile │ ├── client.cc │ ├── server.cc │ └── sleep_service.proto ├── src ├── compile_proto.sh ├── rapidjson │ ├── document.h │ ├── filestream.h │ ├── internal │ │ ├── pow10.h │ │ ├── stack.h │ │ └── strfunc.h │ ├── prettywriter.h │ ├── rapidjson.h │ ├── reader.h │ ├── stringbuffer.h │ └── writer.h └── sofa │ └── pbrpc │ ├── ascii.h │ ├── atomic.h │ ├── bin2ascii.h │ ├── binary_rpc_request.cc │ ├── binary_rpc_request.h │ ├── binary_rpc_request_parser.cc │ ├── binary_rpc_request_parser.h │ ├── block_wrappers.cc │ ├── block_wrappers.h │ ├── boost_system_error_code.cc │ ├── buf_handle.h │ ├── buffer.cc │ ├── buffer.h │ ├── builtin_service.proto │ ├── builtin_service_impl.cc │ ├── builtin_service_impl.h │ ├── closure.h │ ├── closure_gen.pl │ ├── closure_helper.h │ ├── common.cc │ ├── common.h │ ├── common_internal.cc │ ├── common_internal.h │ ├── compressed_stream.cc │ ├── compressed_stream.h │ ├── condition_variable.h │ ├── counter.h │ ├── dynamic_rpc_channel_impl.cc │ ├── dynamic_rpc_channel_impl.h │ ├── ext_closure.h │ ├── ext_closure_gen.pl │ ├── fast_lock.h │ ├── flow_controller.h │ ├── func_tracer.h │ ├── gzip_stream.cc │ ├── gzip_stream.h │ ├── http-agent │ ├── http_agent.cc │ ├── http_agent.h │ └── sofa_pbrpc_client.cc │ ├── http.h │ ├── http_rpc_request.cc │ ├── http_rpc_request.h │ ├── http_rpc_request_parser.cc │ ├── http_rpc_request_parser.h │ ├── io_service.h │ ├── io_service_pool.cc │ ├── io_service_pool.h │ ├── locks.h │ ├── lz4.cc │ ├── lz4.h │ ├── mock_test_helper.cc │ ├── mock_test_helper.h │ ├── mock_test_helper_impl.h │ ├── murmurhash.h │ ├── mutex_lock.h │ ├── pbjson.cc │ ├── pbjson.h │ ├── pbrpc.h │ ├── pprof_perl.h │ ├── profiling.cc │ ├── profiling.h │ ├── profiling_linker.h │ ├── ptime.h │ ├── rpc_byte_stream.h │ ├── rpc_channel.cc │ ├── rpc_channel.h │ ├── rpc_channel_impl.h │ ├── rpc_client.cc │ ├── rpc_client.h │ ├── rpc_client_impl.cc │ ├── rpc_client_impl.h │ ├── rpc_client_stream.h │ ├── rpc_controller.cc │ ├── rpc_controller.h │ ├── rpc_controller_impl.h │ ├── rpc_endpoint.cc │ ├── rpc_endpoint.h │ ├── rpc_error_code.cc │ ├── rpc_error_code.h │ ├── rpc_listener.h │ ├── rpc_message_header.h │ ├── rpc_message_stream.h │ ├── rpc_meta.proto │ ├── rpc_option.proto │ ├── rpc_request.cc │ ├── rpc_request.h │ ├── rpc_request_parser.cc │ ├── rpc_request_parser.h │ ├── rpc_server.cc │ ├── rpc_server.h │ ├── rpc_server_impl.cc │ ├── rpc_server_impl.h │ ├── rpc_server_message_stream.h │ ├── rpc_server_stream.h │ ├── rpc_timeout_manager.h │ ├── rw_lock.h │ ├── scoped_locker.h │ ├── service_pool.h │ ├── simple_rpc_channel_impl.cc │ ├── simple_rpc_channel_impl.h │ ├── smart_ptr │ ├── bad_weak_ptr.hpp │ ├── checked_delete.hpp │ ├── detail │ │ ├── operator_bool.hpp │ │ ├── shared_count.hpp │ │ ├── sp_convertible.hpp │ │ ├── sp_counted_base.hpp │ │ ├── sp_counted_base_gcc_x86.hpp │ │ ├── sp_counted_impl.hpp │ │ ├── spinlock.hpp │ │ ├── spinlock_pool.hpp │ │ └── spinlock_pt.hpp │ ├── enable_shared_from_this.hpp │ ├── memory_order.hpp │ ├── owner_less.hpp │ ├── scoped_array.hpp │ ├── scoped_ptr.hpp │ ├── shared_ptr.hpp │ ├── smart_ptr.hpp │ └── weak_ptr.hpp │ ├── spin_lock.h │ ├── string_utils.cc │ ├── string_utils.h │ ├── tcmalloc_extension_helper.cc │ ├── thread_group.cc │ ├── thread_group.h │ ├── thread_group_impl.h │ ├── timeout_manager.cc │ ├── timeout_manager.h │ ├── timeout_manager_impl.cc │ ├── timeout_manager_impl.h │ ├── timer_worker.h │ ├── tran_buf_pool.h │ ├── viz_min_js.h │ ├── wait_event.h │ ├── web_service.cc │ └── web_service.h ├── test ├── kill_test │ ├── Makefile │ ├── client_parallel.cc │ ├── echo_server.cc │ ├── echo_service.proto │ ├── kill_client_test.sh │ └── kill_server_test.sh └── perf_test │ ├── Makefile │ ├── client_multi_server.cc │ ├── client_multi_thread.cc │ ├── client_parallel.cc │ ├── client_serial.cc │ ├── echo_server.cc │ ├── echo_service.proto │ ├── test_delay.sh │ ├── test_multi_server.sh │ └── test_qps.sh └── unit-test ├── BUILD ├── Makefile ├── depends.mk ├── run_bazel_tests.sh ├── run_test.sh ├── test_atomic.cc ├── test_buffer.cc ├── test_closure.cc ├── test_common.cc ├── test_data.proto ├── test_epoll_support.cc ├── test_ext_closure.cc ├── test_io_service_pool.cc ├── test_thread_group.cc ├── test_timeout_manager.cc ├── test_tran_buf_pool.cc └── test_web_service.cc /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | .cproject 3 | .project 4 | .settings/ 5 | libsofa-pbrpc.a 6 | output/ 7 | sofa-pbrpc-client 8 | unit-test/libgtest.a 9 | unit-test/test_atomic 10 | unit-test/test_buffer 11 | unit-test/test_closure 12 | unit-test/test_common 13 | unit-test/test_data.pb.h 14 | unit-test/test_epoll_support 15 | unit-test/test_ext_closure 16 | unit-test/test_thread_group 17 | unit-test/test_timeout_manager 18 | unit-test/test_tran_buf_pool 19 | unit-test/test_io_service_pool 20 | *.a 21 | sofa-pbrpc-client 22 | depends.mk 23 | src/sofa/pbrpc/*.pb.h 24 | src/sofa/pbrpc/*.pb.cc 25 | 26 | # bazel 27 | bazel-app 28 | bazel-bin 29 | bazel-genfiles 30 | bazel-out 31 | bazel-sofa-pbrpc 32 | bazel-testlogs 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: gcc 3 | env: 4 | global: 5 | - secure: "dRimnJVfqg6IPK758/R+CDeArbtV4yT387ZgJvJLCnKPKC7CZmtVz4xNH+ZQqFzRCDJBBCkpp/0p7Cq5u4f22d4TaAaGf3gK/2okvyNPCg0DUPvVP2LWzfP5pZSwX4/os5axWUGW6//8HDFWK37lQbuLNx+95m93CJP+3StNKzY=" 6 | matrix: 7 | - PROTOBUF_VERSION=2.6.0 8 | before_install: 9 | - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- 10 | install: 11 | - sh -x ./build.sh 12 | - git clone https://github.com/google/googletest.git 13 | script: 14 | - make -j4 && make install 15 | - make -C unit-test -j4 && cd unit-test && ./run_test.sh 16 | addons: 17 | coverity_scan: 18 | project: 19 | name: "baidu/sofa-pbrpc" 20 | description: "Build submitted via Travis CI" 21 | notification_email: shichengyi@baidu.com 22 | build_command_prepend: "make clean" 23 | build_command: "make -j 4" 24 | branch_pattern: master 25 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Names should be added to this file like so: 2 | # Name or Organization 3 | 4 | Baidu.com, Inc. 5 | 6 | # Initial version authors: 7 | Qin Zuoyan 8 | 9 | # Partial list of contributors: 10 | Jiang Jinpeng 11 | Yan Shiguang 12 | 13 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | load("@protobuf//:protobuf.bzl", "cc_proto_library") 2 | 3 | RELATIVE_WELL_KNOWN_PROTOS = [ 4 | "sofa/pbrpc/builtin_service.proto", 5 | "sofa/pbrpc/rpc_meta.proto", 6 | "sofa/pbrpc/rpc_option.proto" 7 | ] 8 | 9 | WELL_KNOWN_PROTOS = ["src/" + s for s in RELATIVE_WELL_KNOWN_PROTOS] 10 | 11 | filegroup( 12 | name = "well_known_protos", 13 | srcs = WELL_KNOWN_PROTOS, 14 | visibility = ["//visibility:public"], 15 | ) 16 | 17 | cc_proto_library( 18 | name = "cc_protos", 19 | srcs = WELL_KNOWN_PROTOS, 20 | include = "src/", 21 | default_runtime = "@protobuf//:protobuf", 22 | protoc = "@protobuf//:protoc", 23 | deps = ["@protobuf//:cc_wkt_protos"], 24 | visibility = ["//visibility:public"] 25 | ) 26 | 27 | cc_library( 28 | name = "rapidjson", 29 | hdrs = glob(["src/rapidjson/*.h", "src/rapidjson/internal/*.h"]), 30 | srcs = [], 31 | visibility = ["//main:__pkg__"], 32 | ) 33 | 34 | cc_library( 35 | name = "sofa-pbrpc", 36 | hdrs = glob([ 37 | "src/sofa/pbrpc/*.h", 38 | "src/sofa/pbrpc/smart_ptr/*.hpp", 39 | "src/sofa/pbrpc/smart_ptr/detail/*.hpp" 40 | ]), 41 | srcs = glob(["src/sofa/pbrpc/*.cc"]), 42 | deps = [ 43 | ":cc_protos", 44 | ":rapidjson", 45 | "@protobuf//:protobuf", 46 | "@protobuf//:protoc_lib", 47 | "@snappy//:snappy", 48 | "@zlib//:zlib", 49 | "@gtest//:gtest", 50 | "@boost//:boost" 51 | ], 52 | copts = [ 53 | "-Iexternal/googletest/include", 54 | ], 55 | visibility = ["//visibility:public"], 56 | ) 57 | 58 | cc_library( 59 | name = "sofa-pbrpc-client-lib", 60 | hdrs = ["src/sofa/pbrpc/http-agent/http_agent.h"], 61 | srcs = ["src/sofa/pbrpc/http-agent/http_agent.cc"], 62 | deps = [ 63 | ":sofa-pbrpc", 64 | ], 65 | visibility = ["//main:__pkg__"], 66 | ) 67 | 68 | cc_binary( 69 | name = "sofa-pbrpc-client", 70 | srcs = [ 71 | "src/sofa/pbrpc/http-agent/sofa_pbrpc_client.cc", 72 | ], 73 | deps = [ 74 | ":sofa-pbrpc-client-lib", 75 | ], 76 | visibility = ["//main:__pkg__"], 77 | ) 78 | 79 | exports_files(["src/sofa/pbrpc/buffer.cc"], ["//unit-test:__pkg__"]) 80 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | 2014-05-20 version 1.0.0: 2 | 3 | * Submit version 1.0.0. 4 | 5 | 2014-07-02 version 1.0.0: 6 | 7 | * Support multi-server load balance. 8 | 9 | 2014-11-19 version 1.0.0: 10 | 11 | * Release version 1.0.0. 12 | 13 | 2014-12-14 version 1.0.1: 14 | 15 | * Support http protocol and web monitor. 16 | 17 | 2015-04-04 version 1.0.1: 18 | 19 | * Support python client. 20 | 21 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Baidu Inc. nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | ---------------------------------------------------------------------- 30 | 31 | Currently, sofa-pbrpc only support x86_64 platform, Linux OS, and GCC. 32 | 33 | 1. Modify file './depends.mk' to specify depending libs. 34 | The necessary libs is boost, protobuf, snappy and zlib, please 35 | refer to file './README' for details. 36 | 2. Run 'make' to build sofa-pbrpc. 37 | The default optimization level is 'O2'. 38 | To change it, modify the 'OPT' variable in file './Makefile'. 39 | 3. Run 'make install' to install sofa-pbrpc. 40 | The default install directory is './output'. 41 | To change it, modify the 'PREFIX' variable in file './Makefile'. 42 | 43 | For any build problem, please contact . 44 | 45 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | sofa-pbrpc 2 | ---------- 3 | A light-weight RPC implement of protobuf RPC framework. 4 | 5 | Wiki: . 6 | 7 | Features 8 | -------- 9 | * High performace. 10 | * Easy to use. Refer to sample codes in './sample'. 11 | * Support sync call and async call. Refer to './sample/echo'. 12 | * Support three level (service/method/request) timeout. Refer to './sample/timeout_sample'. 13 | * Support transparent compression. Refer to './sample/compress_sample'. 14 | * Support mock test. Refer to './sample/mock_sample'. 15 | * Support network flow control. 16 | * Support auto connecting and reconnecting. 17 | * Support keep alive time of idle connections. 18 | * Support statistics for profiling. 19 | * Support multi-server load balance and fault tolerance. 20 | * Support http protocol. 21 | * Provide web monitor. 22 | * Provide python client library. 23 | 24 | Dependings 25 | ---------- 26 | The lib depends on boost-1.53.0 (only need header), protobuf-2.4.1, snappy and zlib: 27 | boost - http://www.boost.org/ 28 | protobuf - https://github.com/google/protobuf 29 | snappy - https://github.com/google/snappy 30 | zlib - http://zlib.net/ 31 | 32 | ATTENTION: boost header is only needed when compiling the lib, but no need for user code. 33 | 34 | Extrally, './unit-test' and './sample/mock_sample' also depends on gtest: 35 | gtest - https://github.com/google/googletest 36 | 37 | Build 38 | ----- 39 | 1, Modify file './depends.mk' to specify depending libs. 40 | The necessary libs is boost, protobuf, snappy and zlib. 41 | 2, Run 'make' to build sofa-pbrpc. 42 | The default optimization level is 'O2'. 43 | To change it, modify the 'OPT' variable in file './Makefile'. 44 | 3, Run 'make install' to install sofa-pbrpc. 45 | The default install directory is './output'. 46 | To change it, modify the 'PREFIX' variable in file './Makefile'. 47 | 48 | For more details, please refer to the wiki. 49 | 50 | Sample 51 | ------ 52 | For sample codes, please refer to './sample' and the wiki. 53 | 54 | Performance 55 | ----------- 56 | For performace details, please refer to the wiki. 57 | 58 | Implementation 59 | ----------- 60 | For implementation details, please refer to the wiki and file 'doc/sofa-pbrpc-document.md'. 61 | 62 | Support 63 | ------- 64 | opensearch@baidu.com 65 | 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | sofa-pbrpc 2 | ========== 3 | [![Build Status](https://travis-ci.org/baidu/sofa-pbrpc.svg)](https://travis-ci.org/baidu/sofa-pbrpc) 4 | [![Join the chat at https://gitter.im/sofa-pbrpc/rpc](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sofa-pbrpc/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link) 5 | [![Coverity Scan Build Status](https://scan.coverity.com/projects/10957/badge.svg)](https://scan.coverity.com/projects/baidu-sofa-pbrpc) 6 | 7 | A light-weight RPC implementation of Google's protobuf RPC framework. 8 | 9 | Wiki: https://github.com/baidu/sofa-pbrpc/wiki 10 | 11 | ### Features 12 | * High performace. 13 | * Easy to use. Refer to sample code in './sample'. 14 | * Supports sync call and async call. Refer to './sample/echo'. 15 | * Supports three level (service/method/request) timeout. Refer to './sample/timeout_sample'. 16 | * Supports transparent compression. Refer to './sample/compress_sample'. 17 | * Supports mock test. Refer to './sample/mock_sample'. 18 | * Supports network flow control. 19 | * Supports auto connecting and reconnecting. 20 | * Supports keep alive time of idle connections. 21 | * Supports statistics for profiling. 22 | * Supports multi-server load balance and fault tolerance. 23 | * Supports http protocol. 24 | * Provides web monitor. 25 | * Provides python client library. 26 | 27 | ### Dependencies 28 | This lib depends on boost-1.53.0 (only need header), protobuf-2.4.1, snappy and zlib: 29 | * boost - http://www.boost.org/ 30 | * protobuf - http://code.google.com/p/protobuf/ 31 | * snappy - http://code.google.com/p/snappy/ 32 | * zlib - http://zlib.net/ 33 | 34 | ATTENTION: boost header is only needed when compiling the lib, but is not needed for user code. 35 | 36 | Extrally, './unit-test' and './sample/mock_sample' also depends on gtest: 37 | * gtest - http://code.google.com/p/googletest/ 38 | 39 | ### Build 40 | 1. Modify the file './depends.mk' to specify depending libs.
41 | The necessary libs are boost, protobuf, snappy, and zlib. 42 | 2. Run 'make' to build sofa-pbrpc.
43 | The default optimization level is 'O2'.
44 | To change it, modify the 'OPT' variable in file './Makefile'. 45 | 3. Run 'make install' to install sofa-pbrpc.
46 | The default install directory is './output'.
47 | To change it, modify the 'PREFIX' variable in file './Makefile'. 48 | 49 | For more details, please refer to the wiki [Build Guide](https://github.com/baidu/sofa-pbrpc/wiki/%E6%9E%84%E5%BB%BA%E6%8C%87%E5%BC%95). 50 | 51 | ### Sample 52 | For sample code, please refer to ['./sample'](https://github.com/baidu/sofa-pbrpc/tree/master/sample) and the wiki [Quick Start](https://github.com/baidu/sofa-pbrpc/wiki/%E5%BF%AB%E9%80%9F%E4%BD%BF%E7%94%A8). 53 | 54 | ### Profiling 55 | For Profiling feature, please refer to the wiki [Profiling](https://github.com/baidu/sofa-pbrpc/wiki/Profiling%E5%8A%9F%E8%83%BD). 56 | 57 | ### Performance 58 | For performace details, please refer to the wiki [Performance](https://github.com/baidu/sofa-pbrpc/wiki/%E6%80%A7%E8%83%BD). 59 | 60 | ### Implementation 61 | For implementation details, please refer to the wiki and file [doc/sofa-pbrpc-document.md](doc/sofa-pbrpc-document.md). 62 | 63 | ### Support 64 | opensearch@baidu.com 65 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Http support 2 | ------------ 3 | Support http protocol, then user can call methods through http, e.g., by browser. 4 | Request and response message may be serialized/deserialized in json format. 5 | This will provide better usability. 6 | (done) 7 | 8 | Multi-server load balance 9 | ------------------------- 10 | By providing multi-server addresses (statically or dynamically), one client stub 11 | can access services deployed on different servers, with intelligent load balance. 12 | (done) 13 | 14 | Cross-language client 15 | --------------------- 16 | Provide rpc client lib in other languages, e.g., java and python. 17 | (python done) 18 | 19 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | git_repository( 2 | name = "protobuf", 3 | remote = "https://github.com/google/protobuf", 4 | tag = "v3.1.0" 5 | ) 6 | 7 | new_git_repository( 8 | name = "snappy", 9 | remote = "https://github.com/google/snappy", 10 | commit = "32d6d7d8a2ef328a2ee1dd40f072e21f4983ebda", # latest master 11 | build_file = "bazel/snappy.BUILD" 12 | ) 13 | 14 | new_git_repository( 15 | name = "gtest", 16 | remote = "https://github.com/google/googletest.git", 17 | tag = "release-1.8.0", 18 | build_file = "bazel/gtest.BUILD", 19 | ) 20 | 21 | new_http_archive( 22 | name = "boost", 23 | url = "https://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.bz2/download", 24 | type = "tar.bz2", 25 | strip_prefix = "boost_1_61_0/", 26 | build_file = "bazel/boost.BUILD", 27 | sha256 = "a547bd06c2fd9a71ba1d169d9cf0339da7ebf4753849a8f7d6fdb8feee99b640", 28 | ) 29 | 30 | new_http_archive( 31 | name = "zlib", 32 | url = "https://sourceforge.net/projects/libpng/files/zlib/1.2.8/zlib-1.2.8.tar.gz/download", 33 | type = "tar.gz", 34 | build_file = "bazel/zlib.BUILD", 35 | strip_prefix = "zlib-1.2.8/", 36 | sha256 = "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d", 37 | ) 38 | -------------------------------------------------------------------------------- /bazel/boost.BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "boost", 3 | srcs = [], 4 | hdrs = glob([ 5 | "boost/**/*.h", 6 | "boost/**/*.hpp", 7 | "boost/**/*.ipp", 8 | "boost/**/*.cc", 9 | ]), 10 | includes = ["."], 11 | visibility = ["//visibility:public"] 12 | ) 13 | -------------------------------------------------------------------------------- /bazel/gtest.BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "gtest", 3 | hdrs = glob([ 4 | "googletest/include/**/*.h", 5 | "googletest/src/*.h" 6 | ]), 7 | srcs = glob( 8 | ["googletest/src/*.cc"], 9 | exclude = ["googletest/src/gtest-all.cc"] 10 | ), 11 | includes = ["googletest/include", "googletest"], 12 | copts = ["-Iexternal/googletest/include"], 13 | linkopts = ["-pthread"], 14 | visibility = ["//visibility:public"], 15 | ) 16 | -------------------------------------------------------------------------------- /bazel/snappy.BUILD: -------------------------------------------------------------------------------- 1 | genrule( 2 | name = "snappy_stubs_public_h", 3 | srcs = [ 4 | "snappy-stubs-public.h.in", 5 | ], 6 | outs = [ 7 | "snappy-stubs-public.h", 8 | ], 9 | cmd = "sed 's/@ac_cv_have_stdint_h@/1/g' $(<) | " + 10 | "sed 's/@ac_cv_have_stddef_h@/1/g' | " + 11 | "sed 's/@ac_cv_have_sys_uio_h@/1/g' | " + 12 | "sed 's/@SNAPPY_MAJOR@/1/g' | " + 13 | "sed 's/@SNAPPY_MINOR@/1/g' | " + 14 | "sed 's/@SNAPPY_PATCHLEVEL@/3/g' >$(@)", 15 | ) 16 | 17 | 18 | cc_library( 19 | name = "snappy", 20 | srcs = [ 21 | "snappy.cc", 22 | "snappy-c.cc", 23 | "snappy-sinksource.cc", 24 | "snappy-stubs-internal.cc", 25 | ], 26 | hdrs = [ 27 | ":snappy_stubs_public_h", 28 | "snappy.h", 29 | "snappy-c.h", 30 | "snappy-internal.h", 31 | "snappy-sinksource.h", 32 | "snappy-stubs-internal.h", 33 | "snappy-stubs-public.h.in", 34 | ], 35 | copts = [ 36 | "-Wno-non-virtual-dtor", 37 | "-Wno-unused-variable", 38 | "-Wno-implicit-fallthrough", 39 | "-Wno-unused-function", 40 | ], 41 | includes = ["."], 42 | visibility = ["//visibility:public"], 43 | ) 44 | -------------------------------------------------------------------------------- /bazel/zlib.BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "zlib", 3 | srcs = [ 4 | "adler32.c", 5 | "compress.c", 6 | "crc32.c", 7 | "deflate.c", 8 | "gzclose.c", 9 | "gzlib.c", 10 | "gzread.c", 11 | "gzwrite.c", 12 | "infback.c", 13 | "inffast.c", 14 | "inflate.c", 15 | "inftrees.c", 16 | "trees.c", 17 | "uncompr.c", 18 | "zutil.c", 19 | ], 20 | hdrs = [ 21 | "crc32.h", 22 | "deflate.h", 23 | "gzguts.h", 24 | "inffast.h", 25 | "inffixed.h", 26 | "inflate.h", 27 | "inftrees.h", 28 | "trees.h", 29 | "zconf.h", 30 | "zlib.h", 31 | "zutil.h", 32 | ], 33 | copts = [ 34 | "-Wno-unused-variable", 35 | "-Wno-implicit-function-declaration", 36 | "-Wno-shift-negative-value", 37 | ], 38 | visibility = ["//visibility:public"] 39 | ) 40 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -x -e 3 | 4 | ######################################## 5 | # download & build depend software 6 | ######################################## 7 | 8 | DEPS_PREFIX=`pwd`/thirdparty 9 | DEPS_CONFIG="--prefix=${DEPS_PREFIX} --disable-shared --with-pic" 10 | FLAG_DIR=`pwd`/.build 11 | 12 | export PATH=${DEPS_PREFIX}/bin:$PATH 13 | mkdir -p ${DEPS_PREFIX} ${FLAG_DIR} 14 | 15 | # boost 16 | if [ ! -f "${FLAG_DIR}/boost_1_57_0" ] \ 17 | || [ ! -d "${DEPS_PREFIX}/boost_1_57_0/boost" ]; then 18 | wget -O ${DEPS_PREFIX}/boost_1_57_0.tar.gz http://sourceforge.net/projects/boost/files/boost/1.57.0/boost_1_57_0.tar.gz 19 | tar zxf ${DEPS_PREFIX}/boost_1_57_0.tar.gz -C ${DEPS_PREFIX} 20 | touch "${FLAG_DIR}/boost_1_57_0" 21 | fi 22 | 23 | # protobuf 24 | if [ ! -f "${FLAG_DIR}/protobuf_2_6_1" ] \ 25 | || [ ! -f "${DEPS_PREFIX}/lib/libprotobuf.a" ] \ 26 | || [ ! -d "${DEPS_PREFIX}/include/google/protobuf" ]; then 27 | wget -O ${DEPS_PREFIX}/protobuf-2.6.1.tar.gz https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz 28 | tar zxf ${DEPS_PREFIX}/protobuf-2.6.1.tar.gz -C ${DEPS_PREFIX} 29 | cd ${DEPS_PREFIX}/protobuf-2.6.1 30 | autoreconf -ivf 31 | ./configure ${DEPS_CONFIG} 32 | make -j4 33 | make install 34 | cd - 35 | touch "${FLAG_DIR}/protobuf_2_6_1" 36 | fi 37 | 38 | # snappy 39 | if [ ! -f "${FLAG_DIR}/snappy_1_1_1" ] \ 40 | || [ ! -f "${DEPS_PREFIX}/lib/libsnappy.a" ] \ 41 | || [ ! -f "${DEPS_PREFIX}/include/snappy.h" ]; then 42 | wget -O ${DEPS_PREFIX}/snappy-1.1.3.tar.gz https://github.com/google/snappy/releases/download/1.1.3/snappy-1.1.3.tar.gz 43 | tar zxf ${DEPS_PREFIX}/snappy-1.1.3.tar.gz -C ${DEPS_PREFIX} 44 | cd ${DEPS_PREFIX}/snappy-1.1.3 45 | ./configure ${DEPS_CONFIG} 46 | make -j4 47 | make install 48 | cd - 49 | touch "${FLAG_DIR}/snappy_1_1_1" 50 | fi 51 | 52 | ######################################## 53 | # config depengs.mk 54 | ######################################## 55 | 56 | echo "BOOST_HEADER_DIR="${DEPS_PREFIX}"/boost_1_57_0" > depends.mk 57 | echo "PROTOBUF_DIR="${DEPS_PREFIX} >> depends.mk 58 | echo "SNAPPY_DIR="${DEPS_PREFIX} >> depends.mk 59 | 60 | ######################################## 61 | # install sofa-pbrpc 62 | ######################################## 63 | 64 | make clean 65 | make -j4 && make install 66 | -------------------------------------------------------------------------------- /depends.mk: -------------------------------------------------------------------------------- 1 | ################################################################ 2 | ## Modified this file to specify depending library path. 3 | ## 4 | ## Depending libs: 5 | ## boost-1.53.0 (only need header) 6 | ## protobuf-2.4.1 7 | ## snappy 8 | ## zlib 9 | ## 10 | ################################################################ 11 | 12 | ################################################################ 13 | ## Boost header directory. 14 | ## 15 | ## Check file exist: 16 | ## $(BOOST_HEADER_DIR)/boost/smart_ptr.hpp 17 | ## 18 | #BOOST_HEADER_DIR=/home/users/qinzuoyan01/libs/boost_1_53_0 19 | BOOST_HEADER_DIR=/usr 20 | ################################################################ 21 | 22 | ################################################################ 23 | ## Protocal Buffers directory containing `include' and `lib'. 24 | ## 25 | ## Check file exist: 26 | ## $(PROTOBUF_DIR)/bin/protoc 27 | ## $(PROTOBUF_DIR)/include/google/protobuf/message.h 28 | ## $(PROTOBUF_DIR)/lib/libprotobuf.a 29 | ## 30 | #PROTOBUF_DIR=/home/users/qinzuoyan01/libs/protobuf-2.4.1/output 31 | PROTOBUF_DIR=/usr/local 32 | ################################################################ 33 | 34 | ################################################################ 35 | ## Snappy directory containing `include' and `lib'. 36 | ## 37 | ## Check file exist: 38 | ## $(SNAPPY_DIR)/include/snappy.h 39 | ## $(SNAPPY_DIR)/lib/libsnappy.a 40 | ## 41 | #SNAPPY_DIR=/home/users/qinzuoyan01/libs/snappy-1.1.1/output 42 | SNAPPY_DIR=/usr 43 | ################################################################ 44 | 45 | ################################################################ 46 | ## Zlib directory containing `include' and `lib'. 47 | ## 48 | ## Check file exist: 49 | ## $(ZLIB_DIR)/include/zlib.h 50 | ## $(ZLIB_DIR)/lib/libz.* 51 | ## 52 | ## If zlib is already installed in system path, ignore ZLIB_DIR. 53 | #ZLIB_DIR= 54 | ################################################################ 55 | 56 | -------------------------------------------------------------------------------- /doc/image/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/arch.png -------------------------------------------------------------------------------- /doc/image/basic_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/basic_arch.png -------------------------------------------------------------------------------- /doc/image/flow-controller-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/flow-controller-result.png -------------------------------------------------------------------------------- /doc/image/flow-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/flow-controller.png -------------------------------------------------------------------------------- /doc/image/network-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/network-arch.png -------------------------------------------------------------------------------- /doc/image/readbuf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/readbuf.png -------------------------------------------------------------------------------- /doc/image/rpc-compress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/rpc-compress.png -------------------------------------------------------------------------------- /doc/image/rpc-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/rpc-header.png -------------------------------------------------------------------------------- /doc/image/rpc-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/rpc-interface.png -------------------------------------------------------------------------------- /doc/image/rpc-thread-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/rpc-thread-1.png -------------------------------------------------------------------------------- /doc/image/rpc-thread-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/rpc-thread-2.png -------------------------------------------------------------------------------- /doc/image/sofa-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/sofa-interface.png -------------------------------------------------------------------------------- /doc/image/stream_layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/stream_layer.png -------------------------------------------------------------------------------- /doc/image/timeout-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/timeout-manager.png -------------------------------------------------------------------------------- /doc/image/writebuf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/doc/image/writebuf.png -------------------------------------------------------------------------------- /image/sofa-pbrpc-cpu-profiling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/image/sofa-pbrpc-cpu-profiling.png -------------------------------------------------------------------------------- /image/sofa-pbrpc-feature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/image/sofa-pbrpc-feature.jpg -------------------------------------------------------------------------------- /image/sofa-pbrpc-flow-control.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/image/sofa-pbrpc-flow-control.jpg -------------------------------------------------------------------------------- /image/sofa-pbrpc-memory-profiling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/image/sofa-pbrpc-memory-profiling.png -------------------------------------------------------------------------------- /image/sofa-pbrpc-performance-delay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/image/sofa-pbrpc-performance-delay.png -------------------------------------------------------------------------------- /image/sofa-pbrpc-performance-qps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/image/sofa-pbrpc-performance-qps.png -------------------------------------------------------------------------------- /image/sofa-pbrpc-web-monitor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/image/sofa-pbrpc-web-monitor.jpg -------------------------------------------------------------------------------- /python/README: -------------------------------------------------------------------------------- 1 | This directory contains the python client lib for sofa-pbrpc. 2 | 3 | Installation 4 | ============ 5 | 6 | 1) Make sure you have Python 2.4 or newer. If in doubt, run: 7 | 8 | $ python -V 9 | 10 | 2) If you do not have setuptools installed, note that it will be 11 | downloaded and installed automatically as soon as you run setup.py. 12 | If you would rather install it manually, you may do so by following 13 | the instructions on this page: 14 | 15 | http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions 16 | 17 | 3) Because this lib depends on the `protoc' tool to compile proto files, 18 | you should set the proper protobuf directory in `../depends.mk', for example: 19 | 20 | PROTOBUF_DIR=/home/users/qinzuoyan01/libs/protobuf-2.4.1/output 21 | 22 | 4) Install: 23 | 24 | $ python setup.py install 25 | 26 | This step may require superuser privileges. Or you can install to other 27 | directory by using `--prefix' or `--install-dir' option: 28 | 29 | $ python setup.py install --prefix=/path/to/install/dir 30 | 31 | Make sure that the `/path/to/install/dir' is exist. 32 | 33 | Usage 34 | ===== 35 | 36 | Sample code: 37 | 38 | from sofa.pbrpc import client 39 | channel = client.Channel("remotehost.example.com:1234") 40 | service = MyService_Stub(channel) 41 | controller = client.Controller() 42 | response = service.MyMethod(controller, request) 43 | if controller.Failed(): 44 | print "[%d] %s" % (controller.ErrorCode(), controller.ErrorText()) 45 | 46 | For more details, see the sample code in `./sample'. 47 | 48 | The complete documentation is available via the web at: 49 | 50 | https://github.com/BaiduPS/sofa-pbrpc/wiki 51 | 52 | -------------------------------------------------------------------------------- /python/compile_proto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Compile depending proto files to *_pb2.py. 4 | 5 | . ../depends.mk 6 | 7 | PROTOC=$PROTOBUF_DIR/bin/protoc 8 | if [ ! -f $PROTOC ] 9 | then 10 | echo "protoc is not found, please set PROTOBUF_DIR in '../depends.mk'." 11 | exit 1 12 | fi 13 | 14 | files="rpc_option.proto rpc_meta.proto builtin_service.proto" 15 | for file in $files 16 | do 17 | input="../src/sofa/pbrpc/$file" 18 | output="./sofa/pbrpc/${file/.proto/_pb2.py}" 19 | echo "Generating $output..." 20 | $PROTOC -I../src -I. -I$PROTOBUF_DIR/include --python_out=. $input 21 | done 22 | 23 | -------------------------------------------------------------------------------- /python/sample/README: -------------------------------------------------------------------------------- 1 | This is a sample code to show how to use python client of sofa-pbrpc. 2 | 3 | Guide 4 | ===== 5 | 6 | 1) Install the python library for protobuf. 7 | 8 | $ cd ${PROTOBUF_SOURCE_DIR}/python 9 | $ python setup.py install 10 | 11 | 2) Install the python client library for sofa-pbrpc. 12 | 13 | $ cd .. 14 | $ python setup.py install 15 | 16 | 3) Generate `echo_service_pb2.py'. 17 | 18 | $ sh compile_proto.sh 19 | 20 | 4) Start the rpc server. 21 | 22 | $ cd ../../sample/echo 23 | $ make 24 | $ ./server 25 | 26 | 5) Run the python client. 27 | 28 | $ python client_sample.py 29 | 30 | -------------------------------------------------------------------------------- /python/sample/client_http_protobuf.py: -------------------------------------------------------------------------------- 1 | # -*- coding:UTF-8 -*- 2 | 3 | # Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 4 | # Use of this source code is governed by a BSD-style license that can be 5 | # found in the LICENSE file. 6 | 7 | # This is a sample code to show how to use python client of sofa-pbrpc. 8 | # 9 | # Preconditions: 10 | # * The protobuf python lib has been installed. 11 | # * The sofa-pbrpc python lib has been installed. 12 | # * The server in ../../sample/echo has been started. 13 | # 14 | # For more, please refer to `./README'. 15 | 16 | from sofa.pbrpc import client 17 | import echo_service_pb2 18 | import sys 19 | import urllib2 20 | 21 | # Prepare post data 22 | echo_request = echo_service_pb2.EchoRequest() 23 | echo_request.message = 'Hello World' 24 | send_data = echo_request.SerializeToString() 25 | 26 | # Prepare http request 27 | url = 'http://localhost:12321/sofa.pbrpc.test.EchoServer.Echo' 28 | accept = 'application/protobuf' 29 | headers = { 'Accept' : accept } 30 | request = urllib2.Request(url, send_data, headers) 31 | 32 | # Send request 33 | try: 34 | response = urllib2.urlopen(request) 35 | except Exception as e: 36 | print "ERROR: Send fail: %s" % e.reason 37 | sys.exit(1) 38 | 39 | # Read http body 40 | recv_data = response.read() 41 | 42 | # check failure 43 | if response.info().getheader('Content-Type') != accept: 44 | print "ERROR: %s" % recv_data 45 | sys.exit(1) 46 | 47 | # print response 48 | echo_response = echo_service_pb2.EchoResponse() 49 | echo_response.ParseFromString(recv_data) 50 | print "Response:\n%s" % echo_response.message 51 | -------------------------------------------------------------------------------- /python/sample/client_sample.py: -------------------------------------------------------------------------------- 1 | # -*- coding:UTF-8 -*- 2 | 3 | # Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 4 | # Use of this source code is governed by a BSD-style license that can be 5 | # found in the LICENSE file. 6 | 7 | # This is a sample code to show how to use python client of sofa-pbrpc. 8 | # 9 | # Preconditions: 10 | # * The protobuf python lib has been installed. 11 | # * The sofa-pbrpc python lib has been installed. 12 | # * The server in ../../sample/echo has been started. 13 | # 14 | # For more, please refer to `./README'. 15 | 16 | from sofa.pbrpc import client 17 | import echo_service_pb2 18 | import sys 19 | 20 | # Create service stub. 21 | channel = client.Channel('127.0.0.1:12321') 22 | service = echo_service_pb2.EchoServer_Stub(channel) 23 | 24 | # Create controller. 25 | # We set timeout to 1.5 seconds by controller.SetTimeout() method. 26 | controller = client.Controller() 27 | controller.SetTimeout(1.5) 28 | 29 | # Prepare request. 30 | request = echo_service_pb2.EchoRequest() 31 | request.message = 'Hello World' 32 | 33 | # Call method. 34 | try: 35 | response = service.Echo(controller, request) 36 | except client.TimeoutError: 37 | print "ERROR: RPC timeout" 38 | sys.exit(1) 39 | except Exception as e: 40 | print "ERROR: RPC fail: %s" % e 41 | sys.exit(1) 42 | 43 | # Check remote failure. 44 | if controller.Failed(): 45 | print "ERROR: Remote fail: %s" % controller.ErrorText() 46 | sys.exit(1) 47 | 48 | # OK, print response. 49 | print "Response:\n\n%s" % response 50 | 51 | -------------------------------------------------------------------------------- /python/sample/compile_proto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Compile depending proto files to *_pb2.py. 4 | 5 | . ../../depends.mk 6 | 7 | PROTOC=$PROTOBUF_DIR/bin/protoc 8 | if [ ! -f $PROTOC ] 9 | then 10 | echo "protoc is not found, please set PROTOBUF_DIR in '../../depends.mk'." 11 | exit 1 12 | fi 13 | 14 | $PROTOC -I. --python_out=. echo_service.proto 15 | 16 | -------------------------------------------------------------------------------- /python/sample/echo_service.proto: -------------------------------------------------------------------------------- 1 | package sofa.pbrpc.test; 2 | 3 | option py_generic_services = true; 4 | 5 | message EchoRequest { 6 | required string message = 1; 7 | } 8 | 9 | message EchoResponse { 10 | required string message = 1; 11 | } 12 | 13 | service EchoServer { 14 | rpc Echo(EchoRequest) returns(EchoResponse); 15 | } 16 | -------------------------------------------------------------------------------- /python/setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | # 3 | # See README for usage instructions. 4 | 5 | from ez_setup import use_setuptools 6 | use_setuptools() 7 | 8 | from setuptools import setup 9 | import sys 10 | import os 11 | import subprocess 12 | 13 | # Find the Protocol Compiler. 14 | proto_dir = None 15 | protoc = None 16 | for line in open("../depends.mk").readlines(): 17 | line = line.strip() 18 | if line.startswith('PROTOBUF_DIR'): 19 | proto_dir = line[line.find('=')+1:] 20 | protoc = proto_dir + "/bin/protoc" 21 | if os.path.exists(protoc): 22 | break 23 | else: 24 | proto_dir = None 25 | protoc = None 26 | 27 | if protoc == None: 28 | sys.stderr.write( 29 | "protoc is not found, please set PROTOBUF_DIR in `../depends.mk'.\n") 30 | sys.exit(-1) 31 | 32 | def generate_proto(source): 33 | """Invokes the Protocol Compiler to generate a _pb2.py from the given 34 | .proto file. Does nothing if the output already exists and is newer than 35 | the input.""" 36 | 37 | output = source.replace(".proto", "_pb2.py").replace("../src/", "") 38 | 39 | if not os.path.exists(source): 40 | print "Can't find required file: " + source 41 | sys.exit(-1) 42 | 43 | if (not os.path.exists(output) or 44 | (os.path.exists(source) and 45 | os.path.getmtime(source) > os.path.getmtime(output))): 46 | print "Generating %s..." % output 47 | protoc_command = [ protoc, "-I../src", "-I.", 48 | "-I"+proto_dir+"/include", "--python_out=.", source ] 49 | if subprocess.call(protoc_command) != 0: 50 | sys.exit(-1) 51 | 52 | if __name__ == '__main__': 53 | if len(sys.argv) >= 2 and sys.argv[1] == "clean": 54 | # Delete generated _pb2.py files and .pyc files in the code tree. 55 | for (dirpath, dirnames, filenames) in os.walk("."): 56 | for filename in filenames: 57 | filepath = os.path.join(dirpath, filename) 58 | if filepath.endswith("_pb2.py") or filepath.endswith(".pyc"): 59 | os.remove(filepath) 60 | else: 61 | generate_proto("../src/sofa/pbrpc/rpc_option.proto") 62 | generate_proto("../src/sofa/pbrpc/rpc_meta.proto") 63 | generate_proto("../src/sofa/pbrpc/builtin_service.proto") 64 | 65 | setup(name = 'sofa-pbrpc', 66 | version = '1.0.1', 67 | description = 'python client for sofa-pbrpc', 68 | maintainer = 'qinzuoyan@gmail.com', 69 | maintainer_email = 'qinzuoyan@gmail.com', 70 | url = 'https://github.com/BaiduPS/sofa-pbrpc', 71 | license = 'BSD License', 72 | packages = [ 'sofa' ], 73 | namespace_packages = [ 'sofa' ], 74 | py_modules = [ 75 | 'sofa.pbrpc.client', 76 | 'sofa.pbrpc.rpc_option_pb2', 77 | 'sofa.pbrpc.rpc_meta_pb2', 78 | 'sofa.pbrpc.builtin_service_pb2' ], 79 | ) 80 | -------------------------------------------------------------------------------- /python/sofa/__init__.py: -------------------------------------------------------------------------------- 1 | __import__('pkg_resources').declare_namespace(__name__) 2 | -------------------------------------------------------------------------------- /python/sofa/pbrpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidu/sofa-pbrpc/fb1a1cbf0b3b0e09706eefdbca8335f48df2f5aa/python/sofa/pbrpc/__init__.py -------------------------------------------------------------------------------- /sample/compress_sample/BUILD: -------------------------------------------------------------------------------- 1 | load("@protobuf//:protobuf.bzl", "cc_proto_library") 2 | 3 | config_setting( 4 | name = "darwin", 5 | values = { 6 | "cpu": "darwin", 7 | }, 8 | visibility = ["//visibility:public"], 9 | ) 10 | 11 | cc_proto_library( 12 | name = "echo_proto", 13 | srcs = [ 14 | "echo_service.proto", 15 | ], 16 | include = ".", 17 | default_runtime = "@protobuf//:protobuf", 18 | protoc = "@protobuf//:protoc", 19 | deps = [ 20 | "//:cc_protos", 21 | ], 22 | ) 23 | 24 | cc_binary( 25 | name = "server", 26 | srcs = ["server.cc"], 27 | 28 | deps = [ 29 | ":echo_proto", 30 | "//:sofa-pbrpc", 31 | "@protobuf//:protobuf", 32 | "@protobuf//:protoc_lib", 33 | ], 34 | linkopts = select({ 35 | ":darwin": [], 36 | "//conditions:default": ["-static"] 37 | }), 38 | visibility = ["//main:__pkg__"], 39 | ) 40 | 41 | cc_binary( 42 | name = "client", 43 | srcs = ["client.cc"], 44 | 45 | deps = [ 46 | ":echo_proto", 47 | "//:sofa-pbrpc", 48 | "@protobuf//:protobuf", 49 | "@protobuf//:protoc_lib", 50 | ], 51 | linkopts = select({ 52 | ":darwin": [], 53 | "//conditions:default": ["-static"] 54 | }), 55 | visibility = ["//main:__pkg__"], 56 | ) 57 | -------------------------------------------------------------------------------- /sample/compress_sample/client.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include "echo_service.pb.h" 7 | 8 | int main(int /*argc*/, char** /*argv*/) 9 | { 10 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 11 | 12 | // Define an rpc client. 13 | sofa::pbrpc::RpcClientOptions client_options; 14 | sofa::pbrpc::RpcClient rpc_client(client_options); 15 | 16 | // Define an rpc channel. 17 | sofa::pbrpc::RpcChannelOptions channel_options; 18 | sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:12321", channel_options); 19 | 20 | // Prepare params. 21 | sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController(); 22 | //cntl->SetTimeout(3000); 23 | sofa::pbrpc::test::EchoRequest* request = 24 | new sofa::pbrpc::test::EchoRequest(); 25 | request->set_message("Hello from qinzuoyan01"); 26 | sofa::pbrpc::test::EchoResponse* response = 27 | new sofa::pbrpc::test::EchoResponse(); 28 | 29 | // Sync call. 30 | sofa::pbrpc::test::EchoServer_Stub* stub = 31 | new sofa::pbrpc::test::EchoServer_Stub(&rpc_channel); 32 | stub->Echo(cntl, request, response, NULL); 33 | int ret = EXIT_SUCCESS; 34 | if (cntl->Failed()) 35 | { 36 | SLOG(ERROR, "request failed: %s", cntl->ErrorText().c_str()); 37 | ret = EXIT_FAILURE; 38 | } 39 | else 40 | { 41 | SLOG(NOTICE, "request succeed: %s", response->message().c_str()); 42 | } 43 | 44 | delete request; 45 | delete response; 46 | delete cntl; 47 | delete stub; 48 | 49 | return ret; 50 | } 51 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 52 | -------------------------------------------------------------------------------- /sample/compress_sample/echo_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "sofa/pbrpc/rpc_option.proto"; 4 | 5 | package sofa.pbrpc.test; 6 | 7 | option cc_generic_services = true; 8 | 9 | message EchoRequest { 10 | required string message = 1; 11 | } 12 | 13 | message EchoResponse { 14 | required string message = 1; 15 | } 16 | 17 | service EchoServer { 18 | rpc Echo(EchoRequest) returns(EchoResponse) { 19 | option (sofa.pbrpc.request_compress_type) = CompressTypeSnappy; 20 | option (sofa.pbrpc.response_compress_type) = CompressTypeSnappy; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /sample/compress_sample/server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | #include "echo_service.pb.h" 9 | 10 | class EchoServerImpl : public sofa::pbrpc::test::EchoServer 11 | { 12 | public: 13 | EchoServerImpl() {} 14 | virtual ~EchoServerImpl() {} 15 | 16 | private: 17 | virtual void Echo(google::protobuf::RpcController* /*controller*/, 18 | const sofa::pbrpc::test::EchoRequest* request, 19 | sofa::pbrpc::test::EchoResponse* response, 20 | google::protobuf::Closure* done) 21 | { 22 | SLOG(NOTICE, "Echo(): request message: %s", request->message().c_str()); 23 | response->set_message("echo message: " + request->message()); 24 | done->Run(); 25 | } 26 | }; 27 | 28 | volatile bool g_quit = false; 29 | 30 | static void SignalIntHandler(int /* sig */) 31 | { 32 | g_quit = true; 33 | } 34 | 35 | int main(int /*argc*/, char** /*argv*/) 36 | { 37 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 38 | 39 | // Define an rpc server. 40 | sofa::pbrpc::RpcServerOptions options; 41 | sofa::pbrpc::RpcServer rpc_server(options); 42 | 43 | // Start rpc server. 44 | if (!rpc_server.Start("0.0.0.0:12321")) { 45 | SLOG(ERROR, "start server failed"); 46 | return EXIT_FAILURE; 47 | } 48 | 49 | sofa::pbrpc::test::EchoServer* echo_service = new EchoServerImpl(); 50 | if (!rpc_server.RegisterService(echo_service)) { 51 | SLOG(ERROR, "export service failed"); 52 | return EXIT_FAILURE; 53 | } 54 | 55 | signal(SIGINT, SignalIntHandler); 56 | signal(SIGTERM, SignalIntHandler); 57 | 58 | while (!g_quit) { 59 | sleep(1); 60 | } 61 | 62 | return EXIT_SUCCESS; 63 | } 64 | 65 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 66 | -------------------------------------------------------------------------------- /sample/echo/BUILD: -------------------------------------------------------------------------------- 1 | load("@protobuf//:protobuf.bzl", "cc_proto_library") 2 | 3 | cc_proto_library( 4 | name = "echo_proto", 5 | srcs = [ 6 | "echo_service.proto", 7 | ], 8 | include = ".", 9 | default_runtime = "@protobuf//:protobuf", 10 | protoc = "@protobuf//:protoc", 11 | ) 12 | 13 | cc_binary( 14 | name = "server", 15 | srcs = ["server.cc"], 16 | 17 | deps = [ 18 | ":echo_proto", 19 | "//:sofa-pbrpc", 20 | "@protobuf//:protobuf", 21 | "@protobuf//:protoc_lib", 22 | ], 23 | visibility = ["//main:__pkg__"], 24 | ) 25 | 26 | cc_binary( 27 | name = "client_async", 28 | srcs = ["client_async.cc"], 29 | 30 | deps = [ 31 | ":echo_proto", 32 | "//:sofa-pbrpc", 33 | "@protobuf//:protobuf", 34 | "@protobuf//:protoc_lib", 35 | ], 36 | visibility = ["//main:__pkg__"], 37 | ) 38 | 39 | cc_binary( 40 | name = "client_sync", 41 | srcs = ["client_sync.cc"], 42 | 43 | deps = [ 44 | ":echo_proto", 45 | "//:sofa-pbrpc", 46 | "@protobuf//:protobuf", 47 | "@protobuf//:protoc_lib", 48 | ], 49 | visibility = ["//main:__pkg__"], 50 | ) 51 | -------------------------------------------------------------------------------- /sample/echo/client_async.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include "echo_service.pb.h" 8 | 9 | void EchoCallback(sofa::pbrpc::RpcController* cntl, 10 | sofa::pbrpc::test::EchoRequest* request, 11 | sofa::pbrpc::test::EchoResponse* response, 12 | bool* callbacked) 13 | { 14 | SLOG(NOTICE, "RemoteAddress=%s", cntl->RemoteAddress().c_str()); 15 | SLOG(NOTICE, "IsRequestSent=%s", cntl->IsRequestSent() ? "true" : "false"); 16 | if (cntl->IsRequestSent()) 17 | { 18 | SLOG(NOTICE, "LocalAddress=%s", cntl->LocalAddress().c_str()); 19 | SLOG(NOTICE, "SentBytes=%ld", cntl->SentBytes()); 20 | } 21 | 22 | if (cntl->Failed()) { 23 | SLOG(ERROR, "request failed: %s", cntl->ErrorText().c_str()); 24 | } 25 | else { 26 | SLOG(NOTICE, "request succeed: %s", response->message().c_str()); 27 | } 28 | 29 | delete cntl; 30 | delete request; 31 | delete response; 32 | *callbacked = true; 33 | } 34 | 35 | int main() 36 | { 37 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 38 | 39 | // Define an rpc server. 40 | sofa::pbrpc::RpcClientOptions client_options; 41 | sofa::pbrpc::RpcClient rpc_client(client_options); 42 | 43 | // Define an rpc channel. 44 | sofa::pbrpc::RpcChannelOptions channel_options; 45 | sofa::pbrpc::RpcChannel rpc_channel(&rpc_client, "127.0.0.1:12321", channel_options); 46 | 47 | // Prepare parameters. 48 | sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController(); 49 | cntl->SetTimeout(3000); 50 | sofa::pbrpc::test::EchoRequest* request = new sofa::pbrpc::test::EchoRequest(); 51 | request->set_message("Hello from qinzuoyan01"); 52 | sofa::pbrpc::test::EchoResponse* response = new sofa::pbrpc::test::EchoResponse(); 53 | bool callbacked = false; 54 | google::protobuf::Closure* done = sofa::pbrpc::NewClosure( 55 | &EchoCallback, cntl, request, response, &callbacked); 56 | 57 | // Async call. 58 | sofa::pbrpc::test::EchoServer_Stub stub(&rpc_channel); 59 | stub.Echo(cntl, request, response, done); 60 | 61 | // Wait call done. 62 | while (!callbacked) { 63 | usleep(100000); 64 | } 65 | 66 | return EXIT_SUCCESS; 67 | } 68 | 69 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 70 | -------------------------------------------------------------------------------- /sample/echo/client_http.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # POST 4 | curl -d '{"message":"Hello, world!"}' http://localhost:12321/sofa.pbrpc.test.EchoServer.Echo 5 | echo 6 | 7 | # GET 8 | curl http://localhost:12321/sofa.pbrpc.test.EchoServer.Echo?request=%7B%22message%22%3A%22Hello%2C%20world%21%22%7D 9 | echo 10 | 11 | -------------------------------------------------------------------------------- /sample/echo/client_sync.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include "echo_service.pb.h" 7 | 8 | // Using global RpcClient object can help share resources such as threads and buffers. 9 | sofa::pbrpc::RpcClient g_rpc_client; 10 | 11 | int main() 12 | { 13 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 14 | 15 | // Define an rpc channel. 16 | sofa::pbrpc::RpcChannelOptions channel_options; 17 | sofa::pbrpc::RpcChannel rpc_channel(&g_rpc_client, "127.0.0.1:12321", channel_options); 18 | 19 | // Prepare parameters. 20 | sofa::pbrpc::RpcController* cntl = new sofa::pbrpc::RpcController(); 21 | cntl->SetTimeout(3000); 22 | sofa::pbrpc::test::EchoRequest* request = 23 | new sofa::pbrpc::test::EchoRequest(); 24 | request->set_message("Hello from qinzuoyan01"); 25 | sofa::pbrpc::test::EchoResponse* response = 26 | new sofa::pbrpc::test::EchoResponse(); 27 | 28 | // Sync call. 29 | sofa::pbrpc::test::EchoServer_Stub* stub = 30 | new sofa::pbrpc::test::EchoServer_Stub(&rpc_channel); 31 | stub->Echo(cntl, request, response, NULL); 32 | 33 | // Check if the request has been sent. 34 | // If has been sent, then can get the sent bytes. 35 | SLOG(NOTICE, "RemoteAddress=%s", cntl->RemoteAddress().c_str()); 36 | SLOG(NOTICE, "IsRequestSent=%s", cntl->IsRequestSent() ? "true" : "false"); 37 | if (cntl->IsRequestSent()) 38 | { 39 | SLOG(NOTICE, "LocalAddress=%s", cntl->LocalAddress().c_str()); 40 | SLOG(NOTICE, "SentBytes=%ld", cntl->SentBytes()); 41 | } 42 | 43 | // Check if failed. 44 | if (cntl->Failed()) 45 | { 46 | SLOG(ERROR, "request failed: %s", cntl->ErrorText().c_str()); 47 | } 48 | else 49 | { 50 | SLOG(NOTICE, "request succeed: %s", response->message().c_str()); 51 | } 52 | 53 | // Destroy objects. 54 | delete cntl; 55 | delete request; 56 | delete response; 57 | delete stub; 58 | 59 | return EXIT_SUCCESS; 60 | } 61 | 62 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 63 | -------------------------------------------------------------------------------- /sample/echo/echo_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package sofa.pbrpc.test; 4 | 5 | option cc_generic_services = true; 6 | option java_generic_services = true; 7 | 8 | message EchoRequest { 9 | required string message = 1; 10 | } 11 | 12 | message EchoResponse { 13 | required string message = 1; 14 | } 15 | 16 | service EchoServer { 17 | rpc Echo(EchoRequest) returns(EchoResponse); 18 | } 19 | -------------------------------------------------------------------------------- /sample/mock_sample/BUILD: -------------------------------------------------------------------------------- 1 | load("@protobuf//:protobuf.bzl", "cc_proto_library") 2 | 3 | cc_proto_library( 4 | name = "echo_proto", 5 | srcs = [ 6 | "echo_service.proto", 7 | ], 8 | include = ".", 9 | default_runtime = "@protobuf//:protobuf", 10 | protoc = "@protobuf//:protoc", 11 | deps = [ 12 | "//:cc_protos", 13 | ], 14 | ) 15 | 16 | cc_binary( 17 | name = "test", 18 | srcs = ["mock_test_sample.cc"], 19 | 20 | deps = [ 21 | ":echo_proto", 22 | "//:sofa-pbrpc", 23 | "@gtest//:gtest", 24 | ], 25 | visibility = ["//main:__pkg__"], 26 | ) 27 | -------------------------------------------------------------------------------- /sample/mock_sample/depends.mk: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | ## Modified this file to specify your library path. 3 | ## 4 | ## Depending libs: 5 | ## gtest-1.7.0 6 | ## 7 | ############################################################### 8 | 9 | ############################################################### 10 | ## Google Test directory. 11 | ## 12 | ## Check file exist: 13 | ## $(GTEST_DIR)/src/gtest-all.cc 14 | ## 15 | #GTEST_DIR=/home/users/qinzuoyan01/libs/gtest-1.7.0 16 | GTEST_DIR=../../googletest/googletest 17 | ############################################################### 18 | 19 | -------------------------------------------------------------------------------- /sample/mock_sample/echo_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package sofa.pbrpc.test; 4 | 5 | option cc_generic_services = true; 6 | 7 | message EchoRequest { 8 | required string message = 1; 9 | } 10 | 11 | message EchoResponse { 12 | required string message = 1; 13 | } 14 | 15 | service EchoServer { 16 | rpc Echo(EchoRequest) returns(EchoResponse); 17 | } 18 | -------------------------------------------------------------------------------- /sample/multi_server_sample/BUILD: -------------------------------------------------------------------------------- 1 | load("@protobuf//:protobuf.bzl", "cc_proto_library") 2 | 3 | cc_proto_library( 4 | name = "echo_proto", 5 | srcs = [ 6 | "echo_service.proto", 7 | ], 8 | include = ".", 9 | default_runtime = "@protobuf//:protobuf", 10 | protoc = "@protobuf//:protoc", 11 | ) 12 | 13 | cc_binary( 14 | name = "server", 15 | srcs = ["server.cc"], 16 | 17 | deps = [ 18 | ":echo_proto", 19 | "//:sofa-pbrpc", 20 | "@protobuf//:protobuf", 21 | "@protobuf//:protoc_lib", 22 | ], 23 | visibility = ["//main:__pkg__"], 24 | ) 25 | 26 | cc_binary( 27 | name = "client", 28 | srcs = ["client.cc"], 29 | 30 | deps = [ 31 | ":echo_proto", 32 | "//:sofa-pbrpc", 33 | "@protobuf//:protobuf", 34 | "@protobuf//:protoc_lib", 35 | ], 36 | visibility = ["//main:__pkg__"], 37 | ) 38 | -------------------------------------------------------------------------------- /sample/multi_server_sample/README: -------------------------------------------------------------------------------- 1 | 1, make 2 | 3 | 2, start servers: 4 | ./server 127.0.0.1 12345 &>/dev/null & 5 | ./server 127.0.0.1 12346 &>/dev/null & 6 | ./server 127.0.0.1 12347 &>/dev/null & 7 | 8 | 3, start client: 9 | ./client address_list.txt 10 | 11 | 4, remove one address from `address_list.txt'. 12 | 13 | 5, signal client to reload address list from `address_list.txt': 14 | killall -s SIGTERM client 15 | 16 | 6, add a new address into `address_list.txt'. 17 | 18 | 7, signal client to reload address list from `address_list.txt': 19 | killall -s SIGTERM client 20 | 21 | 8, test done, stop all servers: 22 | killall server 23 | 24 | -------------------------------------------------------------------------------- /sample/multi_server_sample/address_list.txt: -------------------------------------------------------------------------------- 1 | 127.0.0.1:12345 2 | 127.0.0.1:12346 3 | 127.0.0.1:12347 4 | -------------------------------------------------------------------------------- /sample/multi_server_sample/echo_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package sofa.pbrpc.test; 4 | 5 | option cc_generic_services = true; 6 | option java_generic_services = true; 7 | 8 | message EchoRequest { 9 | required string message = 1; 10 | } 11 | 12 | message EchoResponse { 13 | required string message = 1; 14 | } 15 | 16 | service EchoServer { 17 | rpc Echo(EchoRequest) returns(EchoResponse); 18 | } 19 | -------------------------------------------------------------------------------- /sample/multi_server_sample/server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "echo_service.pb.h" 10 | 11 | class EchoServerImpl : public sofa::pbrpc::test::EchoServer 12 | { 13 | public: 14 | EchoServerImpl() {} 15 | virtual ~EchoServerImpl() {} 16 | 17 | private: 18 | virtual void Echo(google::protobuf::RpcController* controller, 19 | const sofa::pbrpc::test::EchoRequest* request, 20 | sofa::pbrpc::test::EchoResponse* response, 21 | google::protobuf::Closure* done) 22 | { 23 | SLOG(NOTICE, "Echo(): request message from %s: %s", 24 | static_cast(controller)->RemoteAddress().c_str(), 25 | request->message().c_str()); 26 | response->set_message("echo message: " + request->message()); 27 | done->Run(); 28 | } 29 | }; 30 | 31 | bool thread_init_func() 32 | { 33 | sleep(1); 34 | SLOG(INFO, "Init work thread succeed"); 35 | return true; 36 | } 37 | 38 | void thread_dest_func() 39 | { 40 | SLOG(INFO, "Destroy work thread succeed"); 41 | } 42 | 43 | int main(int argc, char** argv) 44 | { 45 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 46 | 47 | if (argc < 3) { 48 | fprintf(stderr, "USAGE: %s \n", argv[0]); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | std::string addr = argv[1] + std::string(":") + argv[2]; 53 | 54 | // Define an rpc server. 55 | sofa::pbrpc::RpcServerOptions options; 56 | options.work_thread_init_func = sofa::pbrpc::NewPermanentExtClosure(&thread_init_func); 57 | options.work_thread_dest_func = sofa::pbrpc::NewPermanentExtClosure(&thread_dest_func); 58 | sofa::pbrpc::RpcServer rpc_server(options); 59 | 60 | // Start rpc server. 61 | if (!rpc_server.Start(addr)) { 62 | SLOG(ERROR, "start server failed"); 63 | return EXIT_FAILURE; 64 | } 65 | 66 | // Register service. 67 | sofa::pbrpc::test::EchoServer* echo_service = new EchoServerImpl(); 68 | if (!rpc_server.RegisterService(echo_service)) { 69 | SLOG(ERROR, "export service failed"); 70 | return EXIT_FAILURE; 71 | } 72 | 73 | // Wait signal. 74 | rpc_server.Run(); 75 | 76 | // Stop rpc server. 77 | rpc_server.Stop(); 78 | 79 | // Delete closures. 80 | // Attention: should delete the closures after server stopped, or may be crash. 81 | delete options.work_thread_init_func; 82 | delete options.work_thread_dest_func; 83 | 84 | return EXIT_SUCCESS; 85 | } 86 | 87 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 88 | -------------------------------------------------------------------------------- /sample/timeout_sample/BUILD: -------------------------------------------------------------------------------- 1 | load("@protobuf//:protobuf.bzl", "cc_proto_library") 2 | 3 | cc_proto_library( 4 | name = "sleep_proto", 5 | srcs = [ 6 | "sleep_service.proto", 7 | ], 8 | include = ".", 9 | default_runtime = "@protobuf//:protobuf", 10 | protoc = "@protobuf//:protoc", 11 | deps = [ 12 | "//:cc_protos", 13 | ], 14 | ) 15 | 16 | cc_binary( 17 | name = "server", 18 | srcs = ["server.cc"], 19 | 20 | deps = [ 21 | ":sleep_proto", 22 | "//:sofa-pbrpc", 23 | "@protobuf//:protobuf", 24 | "@protobuf//:protoc_lib", 25 | ], 26 | visibility = ["//main:__pkg__"], 27 | ) 28 | 29 | cc_binary( 30 | name = "client", 31 | srcs = ["client.cc"], 32 | 33 | deps = [ 34 | ":sleep_proto", 35 | "//:sofa-pbrpc", 36 | "@protobuf//:protobuf", 37 | "@protobuf//:protoc_lib", 38 | ], 39 | visibility = ["//main:__pkg__"], 40 | ) 41 | -------------------------------------------------------------------------------- /sample/timeout_sample/server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "sleep_service.pb.h" 10 | 11 | class SleepServerImpl : public sofa::pbrpc::test::SleepServer 12 | { 13 | public: 14 | SleepServerImpl() {} 15 | virtual ~SleepServerImpl() {} 16 | 17 | virtual void SleepWithServiceTimeout(google::protobuf::RpcController* controller, 18 | const sofa::pbrpc::test::SleepRequest* request, 19 | sofa::pbrpc::test::SleepResponse* response, 20 | google::protobuf::Closure* done) 21 | { 22 | SLOG(NOTICE, "SleepWithServiceTimeout(): request sleep time: %d", request->sleep_time()); 23 | Sleep(controller, request, response, done); 24 | } 25 | 26 | virtual void SleepWithMethodTimeout(google::protobuf::RpcController* controller, 27 | const sofa::pbrpc::test::SleepRequest* request, 28 | sofa::pbrpc::test::SleepResponse* response, 29 | google::protobuf::Closure* done) 30 | { 31 | SLOG(NOTICE, "SleepWithMethodTimeout(): request sleep time: %d", request->sleep_time()); 32 | Sleep(controller, request, response, done); 33 | } 34 | 35 | 36 | private: 37 | void Sleep(google::protobuf::RpcController* controller, 38 | const sofa::pbrpc::test::SleepRequest* request, 39 | sofa::pbrpc::test::SleepResponse* response, 40 | google::protobuf::Closure* done) 41 | { 42 | if (controller->IsCanceled()) 43 | done->Run(); 44 | sleep(request->sleep_time()); 45 | char tmp[100]; 46 | sprintf(tmp, "sleep succeed for %d seconds", request->sleep_time()); 47 | response->set_message(tmp); 48 | done->Run(); 49 | } 50 | }; 51 | 52 | volatile bool g_quit = false; 53 | 54 | static void SignalIntHandler(int /* sig */) 55 | { 56 | g_quit = true; 57 | } 58 | 59 | int main(int /*argc*/, char** /*argv*/) 60 | { 61 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 62 | 63 | // Define an rpc server. 64 | sofa::pbrpc::RpcServerOptions options; 65 | sofa::pbrpc::RpcServer rpc_server(options); 66 | 67 | // Start rpc server. 68 | if (!rpc_server.Start("0.0.0.0:12321")) { 69 | SLOG(ERROR, "start server failed"); 70 | return EXIT_FAILURE; 71 | } 72 | 73 | sofa::pbrpc::test::SleepServer* sleep_service = new SleepServerImpl(); 74 | if (!rpc_server.RegisterService(sleep_service)) { 75 | SLOG(ERROR, "export service failed"); 76 | return EXIT_FAILURE; 77 | } 78 | 79 | signal(SIGINT, SignalIntHandler); 80 | signal(SIGTERM, SignalIntHandler); 81 | 82 | while (!g_quit) { 83 | sleep(1); 84 | } 85 | 86 | return EXIT_SUCCESS; 87 | } 88 | 89 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 90 | -------------------------------------------------------------------------------- /sample/timeout_sample/sleep_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "sofa/pbrpc/rpc_option.proto"; 4 | 5 | package sofa.pbrpc.test; 6 | 7 | option cc_generic_services = true; 8 | 9 | message SleepRequest { 10 | required int32 sleep_time = 1; // in seconds 11 | } 12 | 13 | message SleepResponse { 14 | required string message = 1; 15 | } 16 | 17 | service SleepServer { 18 | // The service timeout is 2 seconds. 19 | option (sofa.pbrpc.service_timeout) = 2000; 20 | 21 | rpc SleepWithServiceTimeout(SleepRequest) returns(SleepResponse); 22 | 23 | // The method timeout is 4 seconds. 24 | rpc SleepWithMethodTimeout(SleepRequest) returns(SleepResponse) { 25 | option (sofa.pbrpc.method_timeout) = 4000; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/compile_proto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PROTO_INCLUDE=$1 4 | 5 | protoc --proto_path=. --proto_path=${PROTO_INCLUDE} --proto_path=/usr/local/include --cpp_out=. \ 6 | sofa/pbrpc/rpc_meta.proto sofa/pbrpc/rpc_option.proto sofa/pbrpc/builtin_service.proto 7 | 8 | -------------------------------------------------------------------------------- /src/rapidjson/filestream.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_FILESTREAM_H_ 2 | #define RAPIDJSON_FILESTREAM_H_ 3 | 4 | #include 5 | 6 | namespace rapidjson { 7 | 8 | //! Wrapper of C file stream for input or output. 9 | /*! 10 | This simple wrapper does not check the validity of the stream. 11 | \implements Stream 12 | */ 13 | class FileStream { 14 | public: 15 | typedef char Ch; //!< Character type. Only support char. 16 | 17 | FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); } 18 | char Peek() const { return current_; } 19 | char Take() { char c = current_; Read(); return c; } 20 | size_t Tell() const { return count_; } 21 | void Put(char c) { fputc(c, fp_); } 22 | 23 | // Not implemented 24 | char* PutBegin() { return 0; } 25 | size_t PutEnd(char*) { return 0; } 26 | 27 | private: 28 | void Read() { 29 | RAPIDJSON_ASSERT(fp_ != 0); 30 | int c = fgetc(fp_); 31 | if (c != EOF) { 32 | current_ = (char)c; 33 | count_++; 34 | } 35 | else 36 | current_ = '\0'; 37 | } 38 | 39 | FILE* fp_; 40 | char current_; 41 | size_t count_; 42 | }; 43 | 44 | } // namespace rapidjson 45 | 46 | #endif // RAPIDJSON_FILESTREAM_H_ 47 | -------------------------------------------------------------------------------- /src/rapidjson/internal/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_INTERNAL_STACK_H_ 2 | #define RAPIDJSON_INTERNAL_STACK_H_ 3 | 4 | namespace rapidjson { 5 | namespace internal { 6 | 7 | /////////////////////////////////////////////////////////////////////////////// 8 | // Stack 9 | 10 | //! A type-unsafe stack for storing different types of data. 11 | /*! \tparam Allocator Allocator for allocating stack memory. 12 | */ 13 | template 14 | class Stack { 15 | public: 16 | Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) { 17 | RAPIDJSON_ASSERT(stack_capacity_ > 0); 18 | if (!allocator_) 19 | own_allocator_ = allocator_ = new Allocator(); 20 | stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_); 21 | stack_end_ = stack_ + stack_capacity_; 22 | } 23 | 24 | ~Stack() { 25 | Allocator::Free(stack_); 26 | delete own_allocator_; // Only delete if it is owned by the stack 27 | } 28 | 29 | void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; } 30 | 31 | template 32 | T* Push(size_t count = 1) { 33 | // Expand the stack if needed 34 | if (stack_top_ + sizeof(T) * count >= stack_end_) { 35 | size_t new_capacity = stack_capacity_ * 2; 36 | size_t size = GetSize(); 37 | size_t new_size = GetSize() + sizeof(T) * count; 38 | if (new_capacity < new_size) 39 | new_capacity = new_size; 40 | stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity); 41 | stack_capacity_ = new_capacity; 42 | stack_top_ = stack_ + size; 43 | stack_end_ = stack_ + stack_capacity_; 44 | } 45 | T* ret = (T*)stack_top_; 46 | stack_top_ += sizeof(T) * count; 47 | return ret; 48 | } 49 | 50 | template 51 | T* Pop(size_t count) { 52 | RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); 53 | stack_top_ -= count * sizeof(T); 54 | return (T*)stack_top_; 55 | } 56 | 57 | template 58 | T* Top() { 59 | RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); 60 | return (T*)(stack_top_ - sizeof(T)); 61 | } 62 | 63 | template 64 | T* Bottom() { return (T*)stack_; } 65 | 66 | Allocator& GetAllocator() { return *allocator_; } 67 | size_t GetSize() const { return stack_top_ - stack_; } 68 | size_t GetCapacity() const { return stack_capacity_; } 69 | 70 | private: 71 | Allocator* allocator_; 72 | Allocator* own_allocator_; 73 | char *stack_; 74 | char *stack_top_; 75 | char *stack_end_; 76 | size_t stack_capacity_; 77 | }; 78 | 79 | } // namespace internal 80 | } // namespace rapidjson 81 | 82 | #endif // RAPIDJSON_STACK_H_ 83 | -------------------------------------------------------------------------------- /src/rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 2 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 3 | 4 | namespace rapidjson { 5 | namespace internal { 6 | 7 | //! Custom strlen() which works on different character types. 8 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 9 | \param s Null-terminated input string. 10 | \return Number of characters in the string. 11 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 12 | */ 13 | template 14 | inline SizeType StrLen(const Ch* s) { 15 | const Ch* p = s; 16 | while (*p != '\0') 17 | ++p; 18 | return SizeType(p - s); 19 | } 20 | 21 | } // namespace internal 22 | } // namespace rapidjson 23 | 24 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 25 | -------------------------------------------------------------------------------- /src/rapidjson/stringbuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_STRINGBUFFER_H_ 2 | #define RAPIDJSON_STRINGBUFFER_H_ 3 | 4 | #include "rapidjson.h" 5 | #include "internal/stack.h" 6 | 7 | namespace rapidjson { 8 | 9 | //! Represents an in-memory output stream. 10 | /*! 11 | \tparam Encoding Encoding of the stream. 12 | \tparam Allocator type for allocating memory buffer. 13 | \implements Stream 14 | */ 15 | template 16 | struct GenericStringBuffer { 17 | typedef typename Encoding::Ch Ch; 18 | 19 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 20 | 21 | void Put(Ch c) { *stack_.template Push() = c; } 22 | 23 | void Clear() { stack_.Clear(); } 24 | 25 | const char* GetString() const { 26 | // Push and pop a null terminator. This is safe. 27 | *stack_.template Push() = '\0'; 28 | stack_.template Pop(1); 29 | 30 | return stack_.template Bottom(); 31 | } 32 | 33 | size_t Size() const { return stack_.GetSize(); } 34 | 35 | static const size_t kDefaultCapacity = 256; 36 | mutable internal::Stack stack_; 37 | }; 38 | 39 | typedef GenericStringBuffer > StringBuffer; 40 | 41 | //! Implement specialized version of PutN() with memset() for better performance. 42 | template<> 43 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { 44 | memset(stream.stack_.Push(n), c, n * sizeof(c)); 45 | } 46 | 47 | } // namespace rapidjson 48 | 49 | #endif // RAPIDJSON_STRINGBUFFER_H_ 50 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/atomic.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_ATOMIC_H_ 6 | #define _SOFA_PBRPC_ATOMIC_H_ 7 | 8 | #if !defined(__i386__) && !defined(__x86_64__) 9 | #error "Arch not supprot!" 10 | #endif 11 | 12 | #include 13 | 14 | namespace sofa { 15 | namespace pbrpc { 16 | 17 | template 18 | inline void atomic_inc(volatile T* n) 19 | { 20 | asm volatile ("lock; incl %0;":"+m"(*n)::"cc"); 21 | } 22 | template 23 | inline void atomic_dec(volatile T* n) 24 | { 25 | asm volatile ("lock; decl %0;":"+m"(*n)::"cc"); 26 | } 27 | template 28 | inline T atomic_add_ret_old(volatile T* n, T v) 29 | { 30 | asm volatile ("lock; xaddl %1, %0;":"+m"(*n),"+r"(v)::"cc"); 31 | return v; 32 | } 33 | template 34 | inline T atomic_inc_ret_old(volatile T* n) 35 | { 36 | T r = 1; 37 | asm volatile ("lock; xaddl %1, %0;":"+m"(*n), "+r"(r)::"cc"); 38 | return r; 39 | } 40 | template 41 | inline T atomic_dec_ret_old(volatile T* n) 42 | { 43 | T r = (T)-1; 44 | asm volatile ("lock; xaddl %1, %0;":"+m"(*n), "+r"(r)::"cc"); 45 | return r; 46 | } 47 | template 48 | inline T atomic_add_ret_old64(volatile T* n, T v) 49 | { 50 | asm volatile ("lock; xaddq %1, %0;":"+m"(*n),"+r"(v)::"cc"); 51 | return v; 52 | } 53 | template 54 | inline T atomic_inc_ret_old64(volatile T* n) 55 | { 56 | T r = 1; 57 | asm volatile ("lock; xaddq %1, %0;":"+m"(*n), "+r"(r)::"cc"); 58 | return r; 59 | } 60 | template 61 | inline T atomic_dec_ret_old64(volatile T* n) 62 | { 63 | T r = (T)-1; 64 | asm volatile ("lock; xaddq %1, %0;":"+m"(*n), "+r"(r)::"cc"); 65 | return r; 66 | } 67 | template 68 | inline void atomic_add(volatile T* n, T v) 69 | { 70 | asm volatile ("lock; addl %1, %0;":"+m"(*n):"r"(v):"cc"); 71 | } 72 | template 73 | inline void atomic_sub(volatile T* n, T v) 74 | { 75 | asm volatile ("lock; subl %1, %0;":"+m"(*n):"r"(v):"cc"); 76 | } 77 | template 78 | inline T atomic_cmpxchg(volatile T* n, C cmp, D dest) 79 | { 80 | asm volatile ("lock; cmpxchgl %1, %0":"+m"(*n), "+r"(dest), "+a"(cmp)::"cc"); 81 | return cmp; 82 | } 83 | // return old value 84 | template 85 | inline T atomic_swap(volatile T* lockword, T value) 86 | { 87 | asm volatile ("lock; xchg %0, %1;" : "+r"(value), "+m"(*lockword)); 88 | return value; 89 | } 90 | template 91 | inline T atomic_comp_swap(volatile T* lockword, E exchange, C comperand) 92 | { 93 | return atomic_cmpxchg(lockword, comperand, exchange); 94 | } 95 | 96 | } // namespace pbrpc 97 | } // namespace sofa 98 | 99 | #endif // _SOFA_PBRPC_ATOMIC_H_ 100 | 101 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 102 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/binary_rpc_request.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_BINARY_RPC_REQUEST_H_ 6 | #define _SOFA_PBRPC_BINARY_RPC_REQUEST_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace sofa { 13 | namespace pbrpc { 14 | 15 | class BinaryRpcRequestParser; 16 | 17 | class BinaryRpcRequest; 18 | typedef sofa::pbrpc::shared_ptr BinaryRpcRequestPtr; 19 | 20 | class BinaryRpcRequest : public RpcRequest 21 | { 22 | public: 23 | BinaryRpcRequest(); 24 | virtual ~BinaryRpcRequest(); 25 | 26 | virtual RpcRequestType RequestType(); 27 | 28 | virtual std::string Method(); 29 | 30 | virtual uint64 SequenceId(); 31 | 32 | virtual void ProcessRequest( 33 | const RpcServerStreamWPtr& server_stream, 34 | const ServicePoolPtr& service_pool); 35 | 36 | virtual ReadBufferPtr AssembleSucceedResponse( 37 | const RpcControllerImplPtr& cntl, 38 | const google::protobuf::Message* response, 39 | std::string& err); 40 | 41 | virtual ReadBufferPtr AssembleFailedResponse( 42 | int32 error_code, 43 | const std::string& reason, 44 | std::string& err); 45 | 46 | private: 47 | friend class BinaryRpcRequestParser; 48 | 49 | RpcMessageHeader _req_header; 50 | RpcMeta _req_meta; 51 | ReadBufferPtr _req_body; 52 | }; // class BinaryRpcRequest 53 | 54 | } // namespace pbrpc 55 | } // namespace sofa 56 | 57 | #endif // _SOFA_PBRPC_BINARY_RPC_REQUEST_H_ 58 | 59 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 60 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/binary_rpc_request_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_BINARY_RPC_REQUEST_PARSER_H_ 6 | #define _SOFA_PBRPC_BINARY_RPC_REQUEST_PARSER_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | class BinaryRpcRequestParser : public RpcRequestParser 15 | { 16 | public: 17 | BinaryRpcRequestParser(); 18 | virtual ~BinaryRpcRequestParser(); 19 | 20 | virtual const char* Name(); 21 | 22 | virtual void Reset(); 23 | 24 | virtual bool CheckMagicString(const char* magic_string); 25 | 26 | virtual int Parse(const char* buf, int data_size, int offset, int* bytes_consumed); 27 | 28 | virtual RpcRequestPtr GetRequest(); 29 | 30 | private: 31 | enum ParseState 32 | { 33 | PS_MAGIC_STRING, 34 | PS_MSG_HEADER, 35 | PS_MSG_BODY 36 | }; 37 | ParseState _state; // current parsing state 38 | int _bytes_recved; // bytes received in current state 39 | BinaryRpcRequestPtr _req; 40 | 41 | static const int64 MAX_MESSAGE_SIZE; 42 | }; // class BinaryRpcRequestParser 43 | 44 | } // namespace pbrpc 45 | } // namespace sofa 46 | 47 | #endif // _SOFA_PBRPC_BINARY_RPC_REQUEST_PARSER_H_ 48 | 49 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 50 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/buf_handle.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_BUF_HANDLE_H_ 6 | #define _SOFA_PBRPC_BUF_HANDLE_H_ 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | struct BufHandle 12 | { 13 | char* data; // block header 14 | int size; // data size 15 | union { 16 | int capacity; // block capacity, used by WriteBuffer 17 | int offset; // start position in the block, used by ReadBuffer 18 | }; 19 | 20 | BufHandle(char* _data, int _capacity) 21 | : data(_data) 22 | , size(0) 23 | , capacity(_capacity) {} 24 | 25 | BufHandle(char* _data, int _size, int _offset) 26 | : data(_data) 27 | , size(_size) 28 | , offset(_offset) {} 29 | }; // class BufHandle 30 | 31 | } // namespace pbrpc 32 | } // namespace sofa 33 | 34 | #endif // _SOFA_PBRPC_BUF_HANDLE_H_ 35 | 36 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 37 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/builtin_service_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_BUILTIN_SERVICE_IMPL_H_ 6 | #define _SOFA_PBRPC_BUILTIN_SERVICE_IMPL_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | namespace builtin { 14 | 15 | class BuiltinServiceImpl : public BuiltinService { 16 | public: 17 | BuiltinServiceImpl(const RpcServerImplWPtr& rpc_server, 18 | const ServicePoolWPtr& service_pool, 19 | bool disable_list_service = false); 20 | virtual ~BuiltinServiceImpl(); 21 | 22 | virtual void Health(::google::protobuf::RpcController* controller, 23 | const ::sofa::pbrpc::builtin::HealthRequest* request, 24 | ::sofa::pbrpc::builtin::HealthResponse* response, 25 | ::google::protobuf::Closure* done); 26 | 27 | virtual void ServerOptions(::google::protobuf::RpcController* controller, 28 | const ::sofa::pbrpc::builtin::ServerOptionsRequest* request, 29 | ::sofa::pbrpc::builtin::ServerOptionsResponse* response, 30 | ::google::protobuf::Closure* done); 31 | 32 | virtual void UpdateOptions(::google::protobuf::RpcController* controller, 33 | const ::sofa::pbrpc::builtin::UpdateOptionsRequest* request, 34 | ::sofa::pbrpc::builtin::UpdateOptionsResponse* response, 35 | ::google::protobuf::Closure* done); 36 | 37 | virtual void ServerStatus(::google::protobuf::RpcController* controller, 38 | const ::sofa::pbrpc::builtin::ServerStatusRequest* request, 39 | ::sofa::pbrpc::builtin::ServerStatusResponse* response, 40 | ::google::protobuf::Closure* done); 41 | 42 | virtual void ListService(::google::protobuf::RpcController* controller, 43 | const ::sofa::pbrpc::builtin::ListServiceRequest* request, 44 | ::sofa::pbrpc::builtin::ListServiceResponse* response, 45 | ::google::protobuf::Closure* done); 46 | 47 | virtual void Stat(::google::protobuf::RpcController* controller, 48 | const ::sofa::pbrpc::builtin::StatRequest* request, 49 | ::sofa::pbrpc::builtin::StatResponse* response, 50 | ::google::protobuf::Closure* done); 51 | 52 | private: 53 | RpcServerImplWPtr _rpc_server; 54 | ServicePoolWPtr _service_pool; 55 | bool _disable_list_service; 56 | 57 | MutexLock _list_service_lock; 58 | ListServiceResponse _list_service_last_response; 59 | int _list_service_last_count; 60 | }; 61 | 62 | } // namespace builtin 63 | } // namespace pbrpc 64 | } // namespace sofa 65 | 66 | #endif // _SOFA_PBRPC_BUILTIN_SERVICE_IMPL_H_ 67 | 68 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 69 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/closure_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_CLOSURE_HELPER_H_ 6 | #define _SOFA_PBRPC_CLOSURE_HELPER_H_ 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | template 12 | inline T * get_pointer(T * p) 13 | { 14 | return p; 15 | } 16 | 17 | // delete p in dtor automatically if Enabled is true 18 | template 19 | class ConditionalAutoDeleter 20 | { 21 | public: 22 | explicit ConditionalAutoDeleter(T* p) 23 | : m_p(p) 24 | { 25 | } 26 | ~ConditionalAutoDeleter() 27 | { 28 | if (Enabled) 29 | { 30 | delete m_p; 31 | } 32 | } 33 | private: 34 | ConditionalAutoDeleter(const ConditionalAutoDeleter&); 35 | ConditionalAutoDeleter& operator=(const ConditionalAutoDeleter&); 36 | private: 37 | T* m_p; 38 | }; 39 | 40 | // This is a typetraits object that's used to take an argument type, and 41 | // extract a suitable type for storing and forwarding arguments. 42 | template 43 | struct ParamTraits 44 | { 45 | typedef const T& ForwardType; 46 | typedef T StorageType; 47 | }; 48 | 49 | template 50 | struct ParamTraits 51 | { 52 | typedef T& ForwardType; 53 | typedef T StorageType; 54 | }; 55 | 56 | } // namespace pbrpc 57 | } // namespace sofa 58 | 59 | #endif // _SOFA_PBRPC_CLOSURE_HELPER_H_ 60 | 61 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 62 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/common_internal.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | 7 | namespace sofa { 8 | namespace pbrpc { 9 | 10 | SOFA_PBRPC_DEFINE_RESOURCE_COUNTER(RpcByteStream); 11 | SOFA_PBRPC_DEFINE_RESOURCE_COUNTER(RpcListener); 12 | 13 | } // namespace pbrpc 14 | } // namespace sofa 15 | 16 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 17 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/compressed_stream.cc: -------------------------------------------------------------------------------- 1 | // This file is modified from `protobuf-zerocopy-compression': 2 | // https://github.com/JohannesEbke/protobuf-zerocopy-compression 3 | 4 | // Copyright (c) 2013, Johannes Ebke and Peter Waller. All rights reserved. 5 | // Author: peter.waller@gmail.com (Peter Waller) 6 | // Author: johannes@ebke.org (Johannes Ebke) 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace sofa { 14 | namespace pbrpc { 15 | 16 | AbstractCompressedInputStream * get_compressed_input_stream( 17 | ZeroCopyInputStream * istream, CompressType type) { 18 | switch(type) { 19 | case CompressTypeGzip: 20 | return new GzipInputStream(istream, GzipInputStream::GZIP); 21 | case CompressTypeZlib: 22 | return new GzipInputStream(istream, GzipInputStream::ZLIB); 23 | case CompressTypeSnappy: 24 | #ifdef HAVE_SNAPPY 25 | return new SnappyInputStream(istream); 26 | #else 27 | SCHECK(false); 28 | #endif 29 | case CompressTypeLZ4: 30 | return new LZ4InputStream(istream); 31 | default: 32 | SCHECK(false); 33 | } 34 | return NULL; 35 | } 36 | 37 | AbstractCompressedOutputStream * get_compressed_output_stream( 38 | ZeroCopyOutputStream * ostream, CompressType type, int level) { 39 | switch (type) { 40 | case CompressTypeGzip: 41 | { 42 | GzipOutputStream::Options o; 43 | o.format = GzipOutputStream::GZIP; 44 | o.compression_level = level; 45 | return new GzipOutputStream(ostream, o); 46 | } 47 | case CompressTypeZlib: 48 | { 49 | GzipOutputStream::Options o; 50 | o.format = GzipOutputStream::ZLIB; 51 | o.compression_level = level; 52 | return new GzipOutputStream(ostream, o); 53 | } 54 | case CompressTypeSnappy: 55 | #ifdef HAVE_SNAPPY 56 | return new SnappyOutputStream(ostream); 57 | #else 58 | SCHECK(false); 59 | #endif 60 | case CompressTypeLZ4: 61 | return new LZ4OutputStream(ostream); 62 | default: 63 | SCHECK(false); 64 | } 65 | return NULL; 66 | } 67 | 68 | } // namespace pbrpc 69 | } // namespace sofa 70 | 71 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 72 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/compressed_stream.h: -------------------------------------------------------------------------------- 1 | // This file is modified from `protobuf-zerocopy-compression': 2 | // https://github.com/JohannesEbke/protobuf-zerocopy-compression 3 | 4 | // Copyright (c) 2013, Johannes Ebke and Peter Waller. All rights reserved. 5 | // Author: peter.waller@gmail.com (Peter Waller) 6 | // Author: johannes@ebke.org (Johannes Ebke) 7 | 8 | #ifndef _SOFA_PBRPC_COMPRESSION_COMPRESSED_STREAM_H_ 9 | #define _SOFA_PBRPC_COMPRESSION_COMPRESSED_STREAM_H_ 10 | 11 | #include 12 | 13 | #include 14 | 15 | #define HAVE_SNAPPY 1 16 | 17 | namespace sofa { 18 | namespace pbrpc { 19 | 20 | /// Base class for all compressed output streams with additional methods 21 | class AbstractCompressedOutputStream : public google::protobuf::io::ZeroCopyOutputStream { 22 | public: 23 | /// Make sure that all data is compressed and written 24 | virtual bool Flush() = 0; 25 | virtual bool Close() = 0; 26 | }; 27 | 28 | /// Base class for all compressed input streams with an ExpectAtEnd method. 29 | class AbstractCompressedInputStream : public google::protobuf::io::ZeroCopyInputStream { 30 | public: 31 | /// ExpectAtEnd returns true if there is no more compressed data to process 32 | virtual bool ExpectAtEnd() = 0; 33 | }; 34 | 35 | ///////////////////////////////////////////////// 36 | // Compress type defined in `rpc_option.proto': 37 | // enum CompressType { 38 | // CompressTypeNone = 0; 39 | // CompressTypeGzip = 1; 40 | // CompressTypeZlib = 2; 41 | // CompressTypeSnappy = 3; 42 | // CompressTypeLZ4 = 4; 43 | // } 44 | ///////////////////////////////////////////////// 45 | 46 | /// Get a pointer to a compressed output stream given an underlying ZeroCopyOutputStream. 47 | /// Specify any of the above compression types, and a compression level (for use in ZLIB). 48 | AbstractCompressedOutputStream * get_compressed_output_stream( 49 | google::protobuf::io::ZeroCopyOutputStream * ostream, CompressType type, int level=1); 50 | 51 | /// Get a pointer to a compressed input stream given an underlying ZeroCopyInputStream. 52 | /// Specify any of the above compression types. 53 | AbstractCompressedInputStream * get_compressed_input_stream( 54 | google::protobuf::io::ZeroCopyInputStream * istream, CompressType type); 55 | 56 | } // namespace pbrpc 57 | } // namespace sofa 58 | 59 | #endif // _SOFA_PBRPC_COMPRESSION_COMPRESSED_STREAM_H_ 60 | 61 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 62 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/condition_variable.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_CONDITION_VARIABLE_H_ 6 | #define _SOFA_PBRPC_CONDITION_VARIABLE_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace sofa { 16 | namespace pbrpc { 17 | 18 | class ConditionVariable 19 | { 20 | public: 21 | ConditionVariable() 22 | { 23 | pthread_cond_init(&_cond, NULL); 24 | } 25 | ~ConditionVariable() 26 | { 27 | pthread_cond_destroy(&_cond); 28 | } 29 | void wait(MutexLock& mutex) 30 | { 31 | SCHECK_EQ(0, pthread_cond_wait(&_cond, &mutex._lock)); 32 | } 33 | bool wait(MutexLock& mutex, int64 timeout_in_ms) 34 | { 35 | if (timeout_in_ms < 0) 36 | { 37 | wait(mutex); 38 | return true; 39 | } 40 | timespec ts; 41 | calculate_expiration(timeout_in_ms, &ts); 42 | int error = pthread_cond_timedwait(&_cond, &mutex._lock, &ts); 43 | if (error == 0) 44 | { 45 | return true; 46 | } 47 | else if (error == ETIMEDOUT) 48 | { 49 | return false; 50 | } 51 | else 52 | { 53 | SLOG(FATAL, "error no: %d", error); 54 | return false; 55 | } 56 | } 57 | void signal() 58 | { 59 | SCHECK_EQ(0, pthread_cond_signal(&_cond)); 60 | } 61 | void broadcast() 62 | { 63 | SCHECK_EQ(0, pthread_cond_broadcast(&_cond)); 64 | } 65 | private: 66 | void calculate_expiration(int64 timeout_in_ms, timespec* ts) 67 | { 68 | timeval tv; 69 | gettimeofday(&tv, NULL); 70 | int64 usec = tv.tv_usec + timeout_in_ms * 1000LL; 71 | ts->tv_sec = tv.tv_sec + usec / 1000000; 72 | ts->tv_nsec = (usec % 1000000) * 1000; 73 | } 74 | private: 75 | pthread_cond_t _cond; 76 | }; 77 | 78 | } // namespace pbrpc 79 | } // namespace sofa 80 | 81 | #endif // _SOFA_PBRPC_CONDITION_VARIABLE_H_ 82 | 83 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 84 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/counter.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_COUNTER_H_ 6 | #define _SOFA_PBRPC_COUNTER_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | 13 | class BasicCounter 14 | { 15 | public: 16 | BasicCounter() : _counter(0) {} 17 | BasicCounter(uint32_t init) : _counter(init) {} 18 | uint32_t operator ++ () 19 | { 20 | return ++ _counter; 21 | } 22 | uint32_t operator -- () 23 | { 24 | return -- _counter; 25 | } 26 | operator uint32_t () const 27 | { 28 | return _counter; 29 | } 30 | private: 31 | uint32_t _counter; 32 | }; 33 | 34 | class AtomicCounter 35 | { 36 | public: 37 | AtomicCounter() : _counter(0) {} 38 | AtomicCounter(uint32_t init) : _counter(init) {} 39 | uint32_t operator ++ () 40 | { 41 | return atomic_inc_ret_old(&_counter) + 1U; 42 | } 43 | uint32_t operator -- () 44 | { 45 | return atomic_dec_ret_old(&_counter) - 1U; 46 | } 47 | operator uint32_t () const 48 | { 49 | return _counter; 50 | } 51 | private: 52 | volatile uint32_t _counter; 53 | }; 54 | 55 | class AtomicCounter64 56 | { 57 | public: 58 | AtomicCounter64() : _counter(0) {} 59 | AtomicCounter64(uint64_t init) : _counter(init) {} 60 | uint64_t operator ++ () 61 | { 62 | return atomic_inc_ret_old64(&_counter) + 1LU; 63 | } 64 | uint64_t operator -- () 65 | { 66 | return atomic_dec_ret_old64(&_counter) - 1LU; 67 | } 68 | operator uint64_t () const 69 | { 70 | return _counter; 71 | } 72 | private: 73 | volatile uint64_t _counter; 74 | }; 75 | 76 | } // namespace pbrpc 77 | } // namespace sofa 78 | 79 | #endif // _SOFA_PBRPC_COUNTER_H_ 80 | 81 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 82 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/fast_lock.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_FAST_LOCK_H_ 6 | #define _SOFA_PBRPC_FAST_LOCK_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | #if defined( SOFA_PBRPC_USE_SPINLOCK ) 15 | typedef SpinLock FastLock; 16 | #else 17 | typedef MutexLock FastLock; 18 | #endif // defined( SOFA_PBRPC_USE_SPINLOCK ) 19 | 20 | } // namespace pbrpc 21 | } // namespace sofa 22 | 23 | #endif // _SOFA_PBRPC_FAST_LOCK_H_ 24 | 25 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 26 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/func_tracer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_FUNC_TRACER_H_ 6 | #define _SOFA_PBRPC_FUNC_TRACER_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace sofa { 13 | namespace pbrpc { 14 | namespace internal { 15 | 16 | class FuncTracer 17 | { 18 | public: 19 | FuncTracer(const char* file, size_t line, const char* func) 20 | : _file(file) 21 | , _line(line) 22 | , _func(func) 23 | { 24 | #if defined( LOG ) 25 | LOG(INFO) << _file << ": " << _line << ": >" << _func << "()"; 26 | #else 27 | SLOG(TRACE, "%s: %u: >%s()", _file, _line, _func); 28 | #endif 29 | } 30 | 31 | ~FuncTracer() 32 | { 33 | #if defined( LOG ) 34 | LOG(INFO) << _file << ": " << _line << ": <" << _func << "()"; 35 | #else 36 | SLOG(TRACE, "%s: %u: <%s()", _file, _line, _func); 37 | #endif 38 | } 39 | 40 | private: 41 | const char* _file; 42 | size_t _line; 43 | const char* _func; 44 | }; // class Tracer 45 | 46 | } // namespace internal 47 | } // namespace pbrpc 48 | } // namespace sofa 49 | 50 | #if defined( SOFA_PBRPC_ENABLE_FUNCTION_TRACE ) 51 | # define SOFA_PBRPC_FUNCTION_TRACE \ 52 | ::sofa::pbrpc::internal::FuncTracer __sofa_function_tracer__( \ 53 | __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) 54 | #else 55 | # define SOFA_PBRPC_FUNCTION_TRACE 56 | #endif // defined( SOFA_PBRPC_ENABLE_FUNCTION_TRACE ) 57 | 58 | #endif // _SOFA_PBRPC_FUNC_TRACER_H_ 59 | 60 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 61 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/http-agent/http_agent.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBPRC_HTTP_AGENT_HTTP_AGENT_H_ 6 | #define _SOFA_PBPRC_HTTP_AGENT_HTTP_AGENT_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace sofa { 18 | namespace pbrpc { 19 | 20 | class RpcControllerImpl; 21 | 22 | namespace builtin { 23 | class BuiltinService_Stub; 24 | } // namespace builtin 25 | 26 | namespace http_agent { 27 | 28 | class HttpAgent 29 | { 30 | public: 31 | HttpAgent(RpcClient* rpc_client); 32 | ~HttpAgent(); 33 | 34 | bool Init(const std::string& server_address); 35 | 36 | bool UpdateServiceInfo(); 37 | 38 | bool ListService(std::map* service_map); 39 | 40 | // Returns map: name --> desc 41 | bool ListService(std::map* desc_map); 42 | 43 | enum ProtobufType { 44 | PT_SERVICE, 45 | PT_MESSAGE, 46 | PT_ENUM, 47 | }; 48 | bool GetDescriptor(const std::string& name, ProtobufType* type, std::string* desc); 49 | 50 | void CallMethod(const std::string& method_full_name, 51 | ::google::protobuf::RpcController* controller, 52 | const std::string* request, 53 | std::string* response, 54 | ::google::protobuf::Closure* done); 55 | 56 | private: 57 | static void CallMethodDone(const sofa::pbrpc::shared_ptr& cntl, 58 | std::string* response, 59 | ::google::protobuf::Message* request_message, 60 | ::google::protobuf::Message* response_message, 61 | ::google::protobuf::Closure* done); 62 | 63 | bool ParseMethodFullName(const std::string& method_full_name, 64 | std::string* service_full_name, std::string* method_name); 65 | 66 | private: 67 | RpcClient* _rpc_client; 68 | RpcChannel* _rpc_channel; 69 | sofa::pbrpc::builtin::BuiltinService_Stub* _stub; 70 | std::string _server_address; 71 | 72 | RWLock _desc_lock; 73 | ::google::protobuf::DescriptorPool* _desc_pool; 74 | ::google::protobuf::MessageFactory* _msg_factory; 75 | typedef std::map ServiceDescriptorMap; 76 | ServiceDescriptorMap _svc_desc_map; 77 | }; 78 | 79 | } // namespace http_agent 80 | } // namespace pbrpc 81 | } // namespace sofa 82 | 83 | #endif // _SOFA_PBPRC_HTTP_AGENT_HTTP_AGENT_H_ 84 | 85 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 86 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/http.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_HTTP_H_ 6 | #define _SOFA_PBRPC_HTTP_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace sofa { 14 | namespace pbrpc { 15 | 16 | /** 17 | * @brief request from http client, include http headers, query_params, and so 18 | * on. 19 | */ 20 | struct HTTPRequest 21 | { 22 | enum Type 23 | { 24 | GET = 1, 25 | POST = 2 26 | }; 27 | 28 | // method in http header 29 | Type type; 30 | 31 | // PATH field in http request 32 | // for example, http://www.baidu.com/s?k=123 33 | // path is "/s" 34 | std::string path; 35 | 36 | // query parameters 37 | // http://www.baidu.com/s?k=123 38 | // will be parsed to {"k":"123"} 39 | const std::map* query_params; 40 | 41 | // http request headers 42 | const std::map* headers; 43 | 44 | // server ip adddress 45 | std::string server_ip; 46 | 47 | // server port 48 | uint16_t server_port; 49 | 50 | // client ip address 51 | std::string client_ip; 52 | 53 | // client port 54 | uint16_t client_port; 55 | 56 | // the body field describes HTTP post body 57 | // using body->ToString() to get the std::string 58 | ReadBufferPtr body; 59 | 60 | HTTPRequest() : type(GET) 61 | , query_params(NULL) 62 | , headers(NULL) 63 | , server_port(0) 64 | , client_port(0) 65 | {} 66 | }; 67 | 68 | /** 69 | * @brief http response to client or web browser 70 | */ 71 | struct HTTPResponse 72 | { 73 | // HTTP server status line, reference to RFC2616 74 | // default value is 200 OK, means this request dealed normally 75 | std::string status_line; 76 | 77 | // content-type field in http response header 78 | // default is "text/html", return a plain text to http client 79 | std::string content_type; 80 | 81 | // page content will return to http client which maybe a web browser 82 | // using content->Append(std::string) to set response body 83 | WriteBufferPtr content; 84 | 85 | HTTPResponse() : status_line("HTTP/1.1 200 OK") 86 | , content_type("text/html; charset=UTF-8") 87 | , content(new WriteBuffer()) 88 | {} 89 | }; 90 | 91 | } // namespace pbrpc 92 | } // namespace sofa 93 | 94 | #endif // _SOFA_PBRPC_HTTP_H_ 95 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/http_rpc_request_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_HTTP_RPC_REQUEST_PARSER_H_ 6 | #define _SOFA_PBRPC_HTTP_RPC_REQUEST_PARSER_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | class HTTPRpcRequestParser : public RpcRequestParser 15 | { 16 | public: 17 | HTTPRpcRequestParser(); 18 | virtual ~HTTPRpcRequestParser(); 19 | 20 | virtual const char* Name(); 21 | 22 | virtual void Reset(); 23 | 24 | virtual bool CheckMagicString(const char* magic_string); 25 | 26 | virtual int Parse(const char* buf, int data_size, int offset, int* bytes_consumed); 27 | 28 | virtual RpcRequestPtr GetRequest(); 29 | 30 | private: 31 | // HTTP state machine based parser. 32 | // 33 | // @retval 1 request data ready 34 | // @retval 0 there are more bytes to be read 35 | // @retval -1 parse request fail, and the error message is returned by err. 36 | int ParseInternal(char c, std::string& err); 37 | 38 | private: 39 | enum ParseState 40 | { 41 | PS_METHOD, 42 | PS_PATH, 43 | PS_HTTP_VERSION, 44 | PS_EXPECT_NEW_LINE1, 45 | PS_HEAD_LINE_START, 46 | PS_HEAD_NAME, 47 | PS_HEAD_COLON, 48 | PS_HEAD_VALUE, 49 | PS_EXPECT_NEW_LINE2, 50 | PS_BODY 51 | }; 52 | ParseState _state; // current parsing state 53 | std::string _header_name; // current parsing header name 54 | std::string _header_value; // currrent parsing header value 55 | int64 _content_length; // body content length 56 | HTTPRpcRequestPtr _req; 57 | static const std::string CONTENT_LENGTH; 58 | static const std::string ACCEPT; 59 | static const std::string ACCEPT_PROTOBUF; 60 | }; // class HTTPRpcRequestParser 61 | 62 | } // namespace pbrpc 63 | } // namespace sofa 64 | 65 | #endif // _SOFA_PBRPC_HTTP_RPC_REQUEST_PARSER_H_ 66 | 67 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 68 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/io_service.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_IO_SERVICE_H_ 6 | #define _SOFA_PBRPC_IO_SERVICE_H_ 7 | 8 | /************************************************************************* 9 | * ATTENTION: we suppose that epoll is always supported on the platform. 10 | 11 | // Linux: epoll, eventfd and timerfd. 12 | #if defined(__linux__) 13 | # include 14 | # if !defined(BOOST_ASIO_DISABLE_EPOLL) 15 | # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) 16 | # define BOOST_ASIO_HAS_EPOLL 1 17 | # endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45) 18 | # endif // !defined(BOOST_ASIO_DISABLE_EVENTFD) 19 | # if !defined(BOOST_ASIO_DISABLE_EVENTFD) 20 | # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) 21 | # define BOOST_ASIO_HAS_EVENTFD 1 22 | # endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) 23 | # endif // !defined(BOOST_ASIO_DISABLE_EVENTFD) 24 | # if defined(BOOST_ASIO_HAS_EPOLL) 25 | # if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) 26 | # define BOOST_ASIO_HAS_TIMERFD 1 27 | # endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) 28 | # endif // defined(BOOST_ASIO_HAS_EPOLL) 29 | #endif // defined(__linux__) 30 | 31 | **************************************************************************/ 32 | #if __APPLE__ 33 | #undef BOOST_ASIO_HAS_EPOLL 34 | #else 35 | #define BOOST_ASIO_HAS_EPOLL 1 36 | #endif 37 | 38 | #include 39 | #include 40 | 41 | namespace sofa { 42 | namespace pbrpc { 43 | 44 | typedef boost::asio::io_service IOService; 45 | typedef sofa::pbrpc::shared_ptr IOServicePtr; 46 | 47 | typedef boost::asio::io_service::work IOServiceWork; 48 | typedef sofa::pbrpc::shared_ptr IOServiceWorkPtr; 49 | 50 | typedef boost::asio::io_service::strand IOServiceStrand; 51 | typedef sofa::pbrpc::shared_ptr IOServiceStrandPtr; 52 | 53 | typedef boost::asio::deadline_timer IOServiceTimer; 54 | typedef sofa::pbrpc::shared_ptr IOServiceTimerPtr; 55 | 56 | } // namespace pbrpc 57 | } // namespace sofa 58 | 59 | #endif // _SOFA_PBRPC_IO_SERVICE_H_ 60 | 61 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 62 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/io_service_pool.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | 7 | namespace sofa { 8 | namespace pbrpc { 9 | 10 | IOServicePool::IOServicePool(std::size_t pool_size, 11 | size_t pool_thread_num) 12 | : _next_service(0) 13 | , _init_func(NULL) 14 | , _dest_func(NULL) 15 | { 16 | assert(pool_size > 0); 17 | 18 | for (size_t i = 0; i < pool_size; ++i) 19 | { 20 | ThreadGroupImplPtr service(new ThreadGroupImpl( 21 | pool_thread_num, "io_service worker thread")); 22 | _pool.push_back(service); 23 | } 24 | } 25 | 26 | bool IOServicePool::Run() 27 | { 28 | size_t pool_size = _pool.size(); 29 | for (size_t i = 0; i < pool_size; ++i) 30 | { 31 | _pool[i]->set_init_func(_init_func); 32 | _pool[i]->set_dest_func(_dest_func); 33 | if (!_pool[i]->start()) 34 | { 35 | #if defined( LOG ) 36 | LOG(ERROR) << "Start(): start work thread group failed"; 37 | #else 38 | SLOG(ERROR, "Start(): start work thread group failed"); 39 | #endif 40 | return false; 41 | } 42 | } 43 | return true; 44 | } 45 | 46 | void IOServicePool::Stop() 47 | { 48 | size_t pool_size = _pool.size(); 49 | for (size_t i = 0; i < pool_size; ++i) 50 | { 51 | _pool[i]->stop(); 52 | _pool[i].reset(); 53 | } 54 | } 55 | 56 | IOService& IOServicePool::GetIOService() 57 | { 58 | IOService& io_service = _pool[_next_service]->io_service(); 59 | ++_next_service; 60 | if (_next_service == _pool.size()) 61 | { 62 | _next_service = 0; 63 | } 64 | return io_service; 65 | } 66 | 67 | } // namespace pbrpc 68 | } // namespace sofa 69 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/io_service_pool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_BINARY_IO_SERVICE_POOL_H_ 6 | #define _SOFA_PBRPC_BINARY_IO_SERVICE_POOL_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace sofa { 13 | namespace pbrpc { 14 | 15 | class IOServicePool 16 | { 17 | public: 18 | IOServicePool(std::size_t pool_size, std::size_t pool_thread_num); 19 | 20 | bool Run(); 21 | 22 | void Stop(); 23 | 24 | IOService& GetIOService(); 25 | 26 | void set_init_func(ThreadInitFunc init_func) 27 | { 28 | _init_func = init_func; 29 | } 30 | 31 | void set_dest_func(ThreadDestFunc dest_func) 32 | { 33 | _dest_func = dest_func; 34 | } 35 | 36 | private: 37 | 38 | std::vector _pool; 39 | 40 | size_t _next_service; 41 | 42 | ThreadInitFunc _init_func; 43 | ThreadDestFunc _dest_func; 44 | 45 | SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(IOServicePool); 46 | }; 47 | 48 | } // namespace pbrpc 49 | } // namespace sofa 50 | 51 | #endif // _SOFA_PBRPC_BINARY_IO_SERVICE_POOL_H_ 52 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/locks.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_LOCKS_H_ 6 | #define _SOFA_PBRPC_LOCKS_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #endif // _SOFA_PBRPC_LOCKS_H_ 16 | 17 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 18 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/mock_test_helper.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | MockTestHelper::MockTestHelper() {} 12 | MockTestHelper::~MockTestHelper() {} 13 | 14 | MockTestHelper* MockTestHelper::GlobalInstance() 15 | { 16 | static MockTestHelperImpl s_mock_channel; 17 | return &s_mock_channel; 18 | } 19 | 20 | bool g_enable_mock = false; 21 | 22 | void enable_mock() 23 | { 24 | MockTestHelper::GlobalInstance(); 25 | g_enable_mock = true; 26 | } 27 | 28 | void disable_mock() 29 | { 30 | g_enable_mock = false; 31 | } 32 | 33 | } // namespace pbrpc 34 | } // namespace sofa 35 | 36 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 37 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/mock_test_helper_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_MOCK_TEST_HELPER_IMPL_H_ 6 | #define _SOFA_PBRPC_MOCK_TEST_HELPER_IMPL_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace sofa { 14 | namespace pbrpc { 15 | 16 | class MockTestHelperImpl : public MockTestHelper 17 | { 18 | public: 19 | MockTestHelperImpl() {} 20 | virtual ~MockTestHelperImpl() {} 21 | 22 | virtual void RegisterMockMethod(const std::string& method_name, 23 | MockMethodHookFunction* mock_method) 24 | { 25 | ScopedLocker _(_lock); 26 | _methods[method_name] = mock_method; 27 | } 28 | 29 | virtual void ClearMockMethod() 30 | { 31 | ScopedLocker _(_lock); 32 | _methods.clear(); 33 | } 34 | 35 | virtual MockMethodHookFunction* GetMockMethod(const std::string& method_name) const 36 | { 37 | ScopedLocker _(_lock); 38 | std::map::const_iterator it = _methods.find(method_name); 39 | return it == _methods.end() ? NULL : it->second; 40 | } 41 | 42 | private: 43 | mutable FastLock _lock; 44 | std::map _methods; 45 | }; 46 | 47 | } // namespace pbrpc 48 | } // namespace sofa 49 | 50 | #endif // _SOFA_PBRPC_MOCK_TEST_HELPER_IMPL_H_ 51 | 52 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 53 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/murmurhash.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBPRC_MURMUR_HASH_H_ 6 | #define _SOFA_PBPRC_MURMUR_HASH_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | 13 | inline uint64_t murmurhash(const void * key, int len) 14 | { 15 | const uint64_t m = 0xc6a4a7935bd1e995; 16 | const int r = 47; 17 | uint64_t h = 0x5bd1e995; 18 | 19 | const uint64_t * data = (const uint64_t *)key; 20 | const uint64_t * end = data + (len/8); 21 | 22 | while(data != end) { 23 | uint64_t k = *data++; 24 | 25 | k *= m; 26 | k ^= k >> r; 27 | k *= m; 28 | 29 | h ^= k; 30 | h *= m; 31 | } 32 | 33 | const unsigned char * data2 = (const unsigned char*)data; 34 | 35 | switch(len & 7) { 36 | case 7: 37 | h ^= uint64_t(data2[6]) << 48; 38 | case 6: 39 | h ^= uint64_t(data2[5]) << 40; 40 | case 5: 41 | h ^= uint64_t(data2[4]) << 32; 42 | case 4: 43 | h ^= uint64_t(data2[3]) << 24; 44 | case 3: 45 | h ^= uint64_t(data2[2]) << 16; 46 | case 2: 47 | h ^= uint64_t(data2[1]) << 8; 48 | case 1: 49 | h ^= uint64_t(data2[0]); 50 | h *= m; 51 | break; 52 | default: 53 | break; 54 | }; 55 | 56 | h ^= h >> r; 57 | h *= m; 58 | h ^= h >> r; 59 | 60 | return h; 61 | } 62 | 63 | inline uint64_t murmurhash(const char* str) 64 | { 65 | return murmurhash((const void*)str, strlen(str)); 66 | } 67 | 68 | } // namespace pbrpc 69 | } // namespace sofa 70 | 71 | #endif // _SOFA_PBPRC_MURMUR_HASH_H_ 72 | 73 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 74 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/mutex_lock.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_MUTEX_LOCK_H_ 6 | #define _SOFA_PBRPC_MUTEX_LOCK_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | class ConditionVariable; 13 | 14 | class MutexLock 15 | { 16 | public: 17 | MutexLock() 18 | { 19 | pthread_mutex_init(&_lock, NULL); 20 | } 21 | ~MutexLock() 22 | { 23 | pthread_mutex_destroy(&_lock); 24 | } 25 | void lock() 26 | { 27 | pthread_mutex_lock(&_lock); 28 | } 29 | void unlock() 30 | { 31 | pthread_mutex_unlock(&_lock); 32 | } 33 | private: 34 | friend class ConditionVariable; 35 | pthread_mutex_t _lock; 36 | }; 37 | 38 | } // namespace pbrpc 39 | } // namespace sofa 40 | 41 | #endif // _SOFA_PBRPC_MUTEX_LOCK_H_ 42 | 43 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 44 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/pbjson.h: -------------------------------------------------------------------------------- 1 | // This file is modified from `yinqiwen/pbjson': 2 | // https://github.com/yinqiwen/pbjson 3 | 4 | /* 5 | * Copyright (c) 2013-2014, yinqiwen 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * * Neither the name of Redis nor the names of its contributors may be used 17 | * to endorse or promote products derived from this software without 18 | * specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 | * THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef _SOFA_PBRPC_PBJSON_H_ 34 | #define _SOFA_PBRPC_PBJSON_H_ 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #define ERR_INVALID_ARG -1 42 | #define ERR_INVALID_PB -2 43 | #define ERR_UNKNOWN_FIELD -3 44 | #define ERR_INVALID_JSON -4 45 | 46 | namespace sofa { 47 | namespace pbrpc { 48 | 49 | void pb2json(const google::protobuf::Message* msg, std::string& str); 50 | rapidjson::Value* pb2jsonobject(const google::protobuf::Message* msg); 51 | rapidjson::Value* pb2jsonobject(const google::protobuf::Message* msg, 52 | rapidjson::Value::AllocatorType& allocator); 53 | void json2string(const rapidjson::Value* json, std::string& str); 54 | 55 | int json2pb(const std::string& json, google::protobuf::Message* msg, std::string& err); 56 | int jsonobject2pb(const rapidjson::Value* json, google::protobuf::Message* msg, std::string& err); 57 | 58 | } // namespace pbrpc 59 | } // namespace sofa 60 | 61 | #endif // _SOFA_PBRPC_PBJSON_H_ 62 | 63 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 64 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/pbrpc.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_PBRPC_H_ 6 | #define _SOFA_PBRPC_PBRPC_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #endif // _SOFA_PBRPC_PBRPC_H_ 28 | 29 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 30 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/profiling.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_PROFILING_H_ 6 | #define _SOFA_PBRPC_PROFILING_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace sofa { 15 | namespace pbrpc { 16 | 17 | class Profiling 18 | { 19 | public: 20 | enum ProfilingType 21 | { 22 | DEFAULT = 1, 23 | CPU = 2, 24 | MEMORY = 4, 25 | }; 26 | 27 | enum OperationType 28 | { 29 | PAGE = 1, 30 | GRAPH = 2, 31 | NEW_GRAPH = 3, 32 | DIFF = 4, 33 | CLEANUP = 5 34 | }; 35 | 36 | typedef std::map OperationMap; 37 | 38 | enum Status 39 | { 40 | OK = 1, 41 | PROFILING = 2, 42 | DISABLE = 3, 43 | FINISHED = 4 44 | }; 45 | 46 | int Init(); 47 | 48 | static Profiling* Instance(); 49 | 50 | OperationType FindOperationType(const std::string& operation_type); 51 | 52 | std::string ProfilingPage(ProfilingType profiling_type, 53 | OperationType operation_type, 54 | std::string& profiling_file, 55 | std::string& profiling_base); 56 | 57 | Status DoCpuProfiling(OperationType operation_type, 58 | std::string& profiling_file); 59 | 60 | Status DoMemoryProfiling(OperationType operation_type, 61 | std::string& profiling_file); 62 | 63 | private: 64 | Profiling(); 65 | 66 | ~Profiling(); 67 | 68 | static void InitProfiling(); 69 | 70 | static void DestroyProfiling(); 71 | 72 | void InitOperationMap(); 73 | 74 | void CpuProfilingFunc(); 75 | 76 | void MemoryProfilingFunc(); 77 | 78 | std::string ShowResult(ProfilingType profiling_type, 79 | const std::string& profiling_file, 80 | const std::string& profiling_base); 81 | 82 | struct EXEDir 83 | { 84 | std::string path; 85 | std::string name; 86 | }; 87 | 88 | private: 89 | volatile bool _is_cpu_profiling; 90 | 91 | volatile bool _is_mem_profiling; 92 | 93 | volatile bool _is_initialized; 94 | 95 | ThreadGroupImplPtr _profiling_thread_group; 96 | 97 | EXEDir _dir; 98 | 99 | static pthread_once_t _init_once; 100 | 101 | static Profiling* _instance; 102 | 103 | OperationMap _operation_map; 104 | 105 | SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(Profiling); 106 | }; 107 | 108 | } // namespace pbrpc 109 | } // namespace sofa 110 | 111 | #endif // _SOFA_PBRPC_PROFILING_H_ 112 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/profiling_linker.h: -------------------------------------------------------------------------------- 1 | #ifndef SOFA_PBRPC_PROFILING_LINKER_H 2 | #define SOFA_PBRPC_PROFILING_LINKER_H 3 | 4 | #if defined(SOFA_PBRPC_PROFILING) 5 | #include 6 | void TCMallocGetHeapSample(std::string* writer); 7 | #endif // SOFA_PBRPC_PROFILING 8 | 9 | extern bool PROFILING_LINKER_FALSE; 10 | 11 | class ProfilingLinker 12 | { 13 | public: 14 | ProfilingLinker() 15 | { 16 | // make libprofiler be linked 17 | if (PROFILING_LINKER_FALSE != false) 18 | { 19 | #if defined(SOFA_PBRPC_PROFILING) 20 | ProfilerStart(NULL); 21 | TCMallocGetHeapSample(NULL); 22 | #endif // SOFA_PBRPC_PROFILING 23 | } 24 | } 25 | }; 26 | 27 | #endif // SOFA_PBRPC_PROFILING_LINKER_H 28 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/ptime.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_PTIME_H_ 6 | #define _SOFA_PBRPC_PTIME_H_ 7 | 8 | #include // for snprintf() 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace sofa { 15 | namespace pbrpc { 16 | 17 | typedef boost::posix_time::ptime PTime; 18 | typedef boost::posix_time::time_duration TimeDuration; 19 | 20 | inline TimeDuration time_duration_microseconds(int64_t); 21 | inline PTime ptime_now() 22 | { 23 | #ifdef __linux__ 24 | struct timespec ts = { 0, 0 }; 25 | clock_gettime(CLOCK_REALTIME, &ts); 26 | time_t microsec = ts.tv_sec * 1000000 + ts.tv_nsec / 1000; 27 | #else 28 | struct timeval tv = { 0, 0 }; 29 | gettimeofday(&tv, NULL); 30 | time_t microsec = tv.tv_sec * 1000000 + tv.tv_usec; 31 | #endif 32 | TimeDuration td = time_duration_microseconds(microsec); 33 | PTime pt(boost::gregorian::date(1970, 1, 1)); 34 | pt += td; 35 | return pt; 36 | } 37 | 38 | inline PTime ptime_infin() 39 | { 40 | return boost::posix_time::ptime(boost::posix_time::pos_infin); 41 | } 42 | 43 | inline std::string ptime_to_string(const PTime& t) 44 | { 45 | // see 46 | typedef boost::date_time::c_local_adjustor local_adj; 47 | PTime lt = local_adj::utc_to_local(t); 48 | PTime::date_type date = lt.date(); 49 | TimeDuration tod = lt.time_of_day(); 50 | char buf[64]; 51 | snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%06ld", 52 | (int)date.year(), 53 | (int)date.month(), 54 | (int)date.day(), 55 | tod.hours(), 56 | tod.minutes(), 57 | tod.seconds(), 58 | tod.fractional_seconds()); 59 | return buf; 60 | } 61 | 62 | inline TimeDuration time_duration_hours(int64_t n) 63 | { 64 | return boost::posix_time::hours(static_cast(n)); 65 | } 66 | 67 | inline TimeDuration time_duration_minutes(int64_t n) 68 | { 69 | return boost::posix_time::minutes(static_cast(n)); 70 | } 71 | 72 | inline TimeDuration time_duration_seconds(int64_t n) 73 | { 74 | return boost::posix_time::seconds(static_cast(n)); 75 | } 76 | 77 | inline TimeDuration time_duration_milliseconds(int64_t n) 78 | { 79 | return boost::posix_time::milliseconds(static_cast(n)); 80 | } 81 | 82 | inline TimeDuration time_duration_microseconds(int64_t n) 83 | { 84 | return boost::posix_time::microseconds(static_cast(n)); 85 | } 86 | 87 | } // namespace pbrpc 88 | } // namespace sofa 89 | 90 | #endif // _SOFA_PBRPC_PTIME_H_ 91 | 92 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 93 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_channel.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | RpcChannel::RpcChannel(RpcClient* rpc_client, 15 | const std::string& server_address, 16 | const RpcChannelOptions& options) 17 | : _impl(new SimpleRpcChannelImpl(rpc_client->impl(), server_address, options)) 18 | { 19 | if (options.create_with_init) 20 | { 21 | _impl->Init(); 22 | } 23 | } 24 | 25 | RpcChannel::RpcChannel(RpcClient* rpc_client, 26 | const std::string& server_ip, 27 | uint32 server_port, 28 | const RpcChannelOptions& options) 29 | { 30 | std::ostringstream os; 31 | os << server_ip << ":" << server_port; 32 | _impl.reset(new SimpleRpcChannelImpl(rpc_client->impl(), os.str(), options)); 33 | if (options.create_with_init) 34 | { 35 | _impl->Init(); 36 | } 37 | } 38 | 39 | RpcChannel::RpcChannel(RpcClient* rpc_client, 40 | const std::vector& address_list, 41 | const RpcChannelOptions& options) 42 | : _impl(new DynamicRpcChannelImpl(rpc_client->impl(), address_list, options)) 43 | { 44 | if (options.create_with_init) 45 | { 46 | _impl->Init(); 47 | } 48 | } 49 | 50 | RpcChannel::RpcChannel(RpcClient* rpc_client, 51 | AddressProvider* address_provider, 52 | const RpcChannelOptions& options) 53 | : _impl(new DynamicRpcChannelImpl(rpc_client->impl(), address_provider, options)) 54 | { 55 | if (options.create_with_init) 56 | { 57 | _impl->Init(); 58 | } 59 | } 60 | 61 | bool RpcChannel::Init() 62 | { 63 | return _impl->Init(); 64 | } 65 | 66 | RpcChannel::~RpcChannel() 67 | { 68 | _impl->Stop(); 69 | } 70 | 71 | void RpcChannel::CallMethod(const ::google::protobuf::MethodDescriptor* method, 72 | ::google::protobuf::RpcController* controller, 73 | const ::google::protobuf::Message* request, 74 | ::google::protobuf::Message* response, 75 | ::google::protobuf::Closure* done) 76 | { 77 | _impl->CallMethod(method, controller, request, response, done); 78 | } 79 | 80 | } // namespace pbrpc 81 | } // namespace sofa 82 | 83 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 84 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_channel_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_RPC_CHANNEL_IMPL_H_ 6 | #define _SOFA_PBRPC_RPC_CHANNEL_IMPL_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | class RpcChannelImpl : public ::google::protobuf::RpcChannel 15 | { 16 | public: 17 | virtual ~RpcChannelImpl() {} 18 | 19 | // Init the channel. 20 | virtual bool Init() = 0; 21 | 22 | // Stop the channel. 23 | virtual void Stop() = 0; 24 | 25 | // Call method. 26 | virtual void CallMethod(const ::google::protobuf::MethodDescriptor* method, 27 | ::google::protobuf::RpcController* controller, 28 | const ::google::protobuf::Message* request, 29 | ::google::protobuf::Message* response, 30 | ::google::protobuf::Closure* done) = 0; 31 | 32 | // Get the count of calls which are not done yet. 33 | virtual uint32 WaitCount() = 0; 34 | }; 35 | 36 | } // namespace pbrpc 37 | } // namespace sofa 38 | 39 | #endif // _SOFA_PBRPC_RPC_CHANNEL_IMPL_H_ 40 | 41 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 42 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_client.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | RpcClient::RpcClient(const RpcClientOptions& options) 12 | { 13 | touch_boost_error_category(); 14 | _impl.reset(new RpcClientImpl(options)); 15 | _impl->Start(); 16 | } 17 | 18 | RpcClient::~RpcClient() 19 | { 20 | Shutdown(); 21 | } 22 | 23 | RpcClientOptions RpcClient::GetOptions() 24 | { 25 | return _impl->GetOptions(); 26 | } 27 | 28 | void RpcClient::ResetOptions(const RpcClientOptions& options) 29 | { 30 | _impl->ResetOptions(options); 31 | } 32 | 33 | int RpcClient::ConnectionCount() 34 | { 35 | return _impl->ConnectionCount(); 36 | } 37 | 38 | void RpcClient::Shutdown() 39 | { 40 | _impl->Stop(); 41 | } 42 | 43 | } // namespace pbrpc 44 | } // namespace sofa 45 | 46 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 47 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_controller.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | RpcController::RpcController() 12 | : _impl(new RpcControllerImpl()) 13 | { 14 | } 15 | 16 | RpcController::~RpcController() 17 | { 18 | } 19 | 20 | std::string RpcController::LocalAddress() const 21 | { 22 | return RpcEndpointToString(_impl->LocalEndpoint()); 23 | } 24 | 25 | std::string RpcController::RemoteAddress() const 26 | { 27 | return RpcEndpointToString(_impl->RemoteEndpoint()); 28 | } 29 | 30 | void RpcController::Reset() 31 | { 32 | _impl.reset(new RpcControllerImpl()); 33 | } 34 | 35 | void RpcController::SetTimeout(int64 timeout_in_ms) 36 | { 37 | _impl->SetTimeout(timeout_in_ms); 38 | } 39 | 40 | int64 RpcController::Timeout() const 41 | { 42 | return _impl->Timeout(); 43 | } 44 | 45 | void RpcController::SetRequestCompressType(CompressType compress_type) 46 | { 47 | _impl->SetRequestCompressType(compress_type); 48 | } 49 | 50 | void RpcController::SetResponseCompressType(CompressType compress_type) 51 | { 52 | _impl->SetResponseCompressType(compress_type); 53 | } 54 | 55 | bool RpcController::Failed() const 56 | { 57 | return _impl->Failed(); 58 | } 59 | 60 | int RpcController::ErrorCode() const 61 | { 62 | return _impl->ErrorCode(); 63 | } 64 | 65 | std::string RpcController::ErrorText() const 66 | { 67 | return _impl->ErrorText(); 68 | } 69 | 70 | bool RpcController::IsRequestSent() const 71 | { 72 | return _impl->IsRequestSent(); 73 | } 74 | 75 | int64 RpcController::SentBytes() const 76 | { 77 | return _impl->SentBytes(); 78 | } 79 | 80 | void RpcController::StartCancel() 81 | { 82 | _impl->StartCancel(); 83 | } 84 | 85 | bool RpcController::IsHttp() const 86 | { 87 | return _impl->IsHttp(); 88 | } 89 | 90 | const std::string& RpcController::HttpPath() const 91 | { 92 | return _impl->HttpPath(); 93 | } 94 | 95 | const std::map& RpcController::HttpQueryParams() const 96 | { 97 | return _impl->HttpQueryParams(); 98 | } 99 | 100 | const std::map& RpcController::HttpHeaders() const 101 | { 102 | return _impl->HttpHeaders(); 103 | } 104 | 105 | void RpcController::SetFailed(const std::string& reason) 106 | { 107 | _impl->SetFailed(reason); 108 | } 109 | 110 | bool RpcController::IsCanceled() const 111 | { 112 | return _impl->IsCanceled(); 113 | } 114 | 115 | void RpcController::NotifyOnCancel(google::protobuf::Closure* callback) 116 | { 117 | _impl->NotifyOnCancel(callback); 118 | } 119 | 120 | } // namespace pbrpc 121 | } // namespace sofa 122 | 123 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 124 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_endpoint.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace sofa { 10 | namespace pbrpc { 11 | 12 | using boost::asio::ip::tcp; 13 | 14 | std::string RpcEndpointToString(const RpcEndpoint& endpoint) 15 | { 16 | std::stringstream ss; 17 | ss << endpoint; 18 | return ss.str(); 19 | } 20 | 21 | std::string HostOfRpcEndpoint(const RpcEndpoint& endpoint) 22 | { 23 | return endpoint.address().to_string(); 24 | } 25 | 26 | uint32 PortOfRpcEndpoint(const RpcEndpoint& endpoint) 27 | { 28 | return endpoint.port(); 29 | } 30 | 31 | bool ResolveAddress(IOService& io_service, 32 | const std::string& host, const std::string& svc, 33 | RpcEndpoint* endpoint) 34 | { 35 | tcp::resolver resolver(io_service); 36 | boost::system::error_code ec; 37 | tcp::resolver::iterator it = resolver.resolve(tcp::resolver::query(host, svc), ec), end; 38 | if (it != end) 39 | { 40 | *endpoint = it->endpoint(); 41 | return true; 42 | } 43 | else 44 | { 45 | #if defined( LOG ) 46 | LOG(ERROR) << "ResolveAddress(): resolve address [" 47 | << host << ":" << svc << "] failed: " << ec.message(); 48 | #else 49 | SLOG(ERROR, "ResolveAddress(): resolve address [%s:%s] failed: %s", 50 | host.c_str(), svc.c_str(), ec.message().c_str()); 51 | #endif 52 | return false; 53 | } 54 | } 55 | 56 | bool ResolveAddress(IOService& io_service, 57 | const std::string& address, 58 | RpcEndpoint* endpoint) 59 | { 60 | std::string::size_type pos = address.find(':'); 61 | if (pos == std::string::npos) 62 | { 63 | #if defined( LOG ) 64 | LOG(ERROR) << "ResolveAddress(): invalid address: " << address; 65 | #else 66 | SLOG(ERROR, "ResolveAddress(): invalid address: %s", address.c_str()); 67 | #endif 68 | return false; 69 | } 70 | std::string host = address.substr(0, pos); 71 | std::string svc = address.substr(pos + 1); 72 | return ResolveAddress(io_service, host, svc, endpoint); 73 | } 74 | 75 | } // namespace pbrpc 76 | } // namespace sofa 77 | 78 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 79 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_endpoint.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_RPC_ENDPOINT_H_ 6 | #define _SOFA_PBRPC_RPC_ENDPOINT_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | 13 | // RpcEndpoint is a tuple . 14 | typedef boost::asio::ip::tcp::endpoint RpcEndpoint; 15 | 16 | // Convert RpcEndpoint to string. 17 | std::string RpcEndpointToString(const RpcEndpoint& endpoint); 18 | 19 | // Get host of RpcEndpoint. 20 | std::string HostOfRpcEndpoint(const RpcEndpoint& endpoint); 21 | 22 | // Get port of RpcEndpoint. 23 | uint32 PortOfRpcEndpoint(const RpcEndpoint& endpoint); 24 | 25 | // DNS resolve server address to RpcEndpoint, only choose the first one. 26 | // @param io_service is the io service used for resolving. 27 | // @param host can be an ip or host name, eg. "127.0.0.1" or "baidu.com". 28 | // @param svc can be a port or service name, eg. "21" or "ftp". 29 | // @param endpoints is out param, stores resolved RpcEndpoint if succeed, 30 | // but may be empty. 31 | // @return true if resolve succeed. 32 | // @return false if resolve failed. 33 | bool ResolveAddress(IOService& io_service, 34 | const std::string& host, const std::string& svc, 35 | RpcEndpoint* endpoint); 36 | 37 | // DNS resolve server address to RpcEndpoint, only choose the first one. 38 | // @param io_service is the io service used for resolving. 39 | // @param server address should be in format of "host:port". 40 | // @param endpoint is out param, stores resolved RpcEndpoint if succeed. 41 | // @return true if resolve succeed. 42 | // @return false if resolve failed or not address found. 43 | bool ResolveAddress(IOService& io_service, 44 | const std::string& address, 45 | RpcEndpoint* endpoint); 46 | 47 | } // namespace pbrpc 48 | } // namespace sofa 49 | 50 | #endif // _SOFA_PBRPC_RPC_ENDPOINT_H_ 51 | 52 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 53 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_error_code.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | 7 | namespace sofa { 8 | namespace pbrpc { 9 | 10 | #define MAKE_CASE(name) case name: return (#name) 11 | 12 | const char* RpcErrorCodeToString(int error_code) 13 | { 14 | switch(error_code) 15 | { 16 | MAKE_CASE(RPC_SUCCESS); 17 | 18 | MAKE_CASE(RPC_ERROR_PARSE_REQUEST_MESSAGE); 19 | MAKE_CASE(RPC_ERROR_PARSE_RESPONSE_MESSAGE); 20 | MAKE_CASE(RPC_ERROR_UNCOMPRESS_MESSAGE); 21 | MAKE_CASE(RPC_ERROR_COMPRESS_TYPE); 22 | MAKE_CASE(RPC_ERROR_NOT_SPECIFY_METHOD_NAME); 23 | MAKE_CASE(RPC_ERROR_PARSE_METHOD_NAME); 24 | MAKE_CASE(RPC_ERROR_FOUND_SERVICE); 25 | MAKE_CASE(RPC_ERROR_FOUND_METHOD); 26 | MAKE_CASE(RPC_ERROR_CHANNEL_BROKEN); 27 | MAKE_CASE(RPC_ERROR_CONNECTION_CLOSED); 28 | MAKE_CASE(RPC_ERROR_REQUEST_TIMEOUT); 29 | MAKE_CASE(RPC_ERROR_REQUEST_CANCELED); 30 | MAKE_CASE(RPC_ERROR_SERVER_UNAVAILABLE); 31 | MAKE_CASE(RPC_ERROR_SERVER_UNREACHABLE); 32 | MAKE_CASE(RPC_ERROR_SERVER_SHUTDOWN); 33 | MAKE_CASE(RPC_ERROR_SEND_BUFFER_FULL); 34 | MAKE_CASE(RPC_ERROR_SERIALIZE_REQUEST); 35 | MAKE_CASE(RPC_ERROR_SERIALIZE_RESPONSE); 36 | MAKE_CASE(RPC_ERROR_RESOLVE_ADDRESS); 37 | MAKE_CASE(RPC_ERROR_CREATE_STREAM); 38 | MAKE_CASE(RPC_ERROR_NOT_IN_RUNNING); 39 | MAKE_CASE(RPC_ERROR_SERVER_BUSY); 40 | 41 | MAKE_CASE(RPC_ERROR_TOO_MANY_OPEN_FILES); 42 | 43 | MAKE_CASE(RPC_ERROR_UNKNOWN); 44 | MAKE_CASE(RPC_ERROR_FROM_USER); 45 | } 46 | return "RPC_ERROR_UNDEFINED"; 47 | } 48 | 49 | } // namespace pbrpc 50 | } // namespace sofa 51 | 52 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 53 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_error_code.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_RPC_ERROR_CODE_H_ 6 | #define _SOFA_PBRPC_RPC_ERROR_CODE_H_ 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | enum RpcErrorCode { 12 | RPC_SUCCESS = 0, 13 | RPC_ERROR_PARSE_REQUEST_MESSAGE = 1, 14 | RPC_ERROR_PARSE_RESPONSE_MESSAGE = 2, 15 | RPC_ERROR_UNCOMPRESS_MESSAGE = 3, 16 | RPC_ERROR_COMPRESS_TYPE = 4, 17 | RPC_ERROR_NOT_SPECIFY_METHOD_NAME = 5, 18 | RPC_ERROR_PARSE_METHOD_NAME = 6, 19 | RPC_ERROR_FOUND_SERVICE = 7, 20 | RPC_ERROR_FOUND_METHOD = 8, 21 | RPC_ERROR_CHANNEL_BROKEN = 9, 22 | RPC_ERROR_CONNECTION_CLOSED = 10, 23 | RPC_ERROR_REQUEST_TIMEOUT = 11, // request timeout 24 | RPC_ERROR_REQUEST_CANCELED = 12, // request canceled 25 | RPC_ERROR_SERVER_UNAVAILABLE = 13, // server un-healthy 26 | RPC_ERROR_SERVER_UNREACHABLE = 14, // server un-reachable 27 | RPC_ERROR_SERVER_SHUTDOWN = 15, 28 | RPC_ERROR_SEND_BUFFER_FULL = 16, 29 | RPC_ERROR_SERIALIZE_REQUEST = 17, 30 | RPC_ERROR_SERIALIZE_RESPONSE = 18, 31 | RPC_ERROR_RESOLVE_ADDRESS = 19, 32 | RPC_ERROR_CREATE_STREAM = 20, 33 | RPC_ERROR_NOT_IN_RUNNING = 21, 34 | RPC_ERROR_SERVER_BUSY = 22, 35 | 36 | // error code for listener 37 | RPC_ERROR_TOO_MANY_OPEN_FILES = 101, 38 | 39 | RPC_ERROR_UNKNOWN = 999, 40 | RPC_ERROR_FROM_USER = 1000, 41 | }; // enum RpcErrorCode 42 | 43 | // Convert rpc error code to human readable string. 44 | const char* RpcErrorCodeToString(int error_code); 45 | 46 | } // namespace pbrpc 47 | } // namespace sofa 48 | 49 | #endif // _SOFA_PBRPC_RPC_ERROR_CODE_H_ 50 | 51 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 52 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_message_header.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_RPC_MESSAGE_HEADER_H_ 6 | #define _SOFA_PBRPC_RPC_MESSAGE_HEADER_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | 13 | // Magic string "SOFA" in little endian. 14 | #define SOFA_RPC_MAGIC 1095126867u 15 | 16 | // total 24 bytes 17 | struct RpcMessageHeader { 18 | union { 19 | char magic_str[4]; 20 | uint32 magic_str_value; 21 | }; // 4 bytes 22 | int32 meta_size; // 4 bytes 23 | int64 data_size; // 8 bytes 24 | int64 message_size; // 8 bytes: message_size = meta_size + data_size, for check 25 | 26 | RpcMessageHeader() 27 | : magic_str_value(SOFA_RPC_MAGIC) 28 | , meta_size(0), data_size(0), message_size(0) {} 29 | 30 | bool CheckMagicString() const 31 | { 32 | return magic_str_value == SOFA_RPC_MAGIC; 33 | } 34 | }; 35 | 36 | } // namespace pbrpc 37 | } // namespace sofa 38 | 39 | #endif // _SOFA_PBRPC_RPC_MESSAGE_HEADER_H_ 40 | 41 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 42 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_meta.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | syntax = "proto2"; 6 | 7 | import "sofa/pbrpc/rpc_option.proto"; 8 | 9 | package sofa.pbrpc; 10 | 11 | message RpcMeta { 12 | 13 | ///////////////////////////////////////////////////// 14 | // The following fields are used both for request and response. 15 | 16 | // Message type. 17 | enum Type { 18 | REQUEST = 0; 19 | RESPONSE = 1; 20 | }; 21 | required Type type = 1; 22 | 23 | // Message sequence id. 24 | required uint64 sequence_id = 2; 25 | 26 | ///////////////////////////////////////////////////// 27 | // The following fields are used only for request. 28 | 29 | // Method full name. 30 | // For example: "test.HelloService.GreetMethod" 31 | optional string method = 100; 32 | 33 | // Server timeout in milli-seconds. 34 | optional int64 server_timeout = 101; 35 | 36 | ///////////////////////////////////////////////////// 37 | // The following fields are used only for response. 38 | 39 | // Set as true if the call is failed. 40 | optional bool failed = 200; 41 | 42 | // The error code if the call is failed. 43 | optional int32 error_code = 201; 44 | 45 | // The error reason if the call is failed. 46 | optional string reason = 202; 47 | 48 | ///////////////////////////////////////////////////// 49 | // Compression related fields. 50 | 51 | // Set the request/response compress type. 52 | optional CompressType compress_type = 300; 53 | 54 | // Set the response compress type of user expected. 55 | optional CompressType expected_response_compress_type = 301; 56 | } 57 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_option.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | syntax = "proto2"; 5 | 6 | import "google/protobuf/descriptor.proto"; 7 | 8 | package sofa.pbrpc; 9 | 10 | extend google.protobuf.ServiceOptions { 11 | // Timeout in milli-seconds at service level. Default is 10 seconds. 12 | optional int64 service_timeout = 20000 [default = 10000]; 13 | } 14 | 15 | enum CompressType { 16 | CompressTypeNone = 0; 17 | CompressTypeGzip = 1; 18 | CompressTypeZlib = 2; 19 | CompressTypeSnappy = 3; 20 | CompressTypeLZ4 = 4; 21 | } 22 | 23 | extend google.protobuf.MethodOptions { 24 | // Timeout in milli-seconds at method level. There is no default value because 25 | // method without method_timeout set will use service_timeout. 26 | optional int64 method_timeout = 20000; 27 | 28 | // Compress type. Default is no compression. 29 | optional CompressType request_compress_type = 20001 [default = CompressTypeNone]; 30 | optional CompressType response_compress_type = 20002 [default = CompressTypeNone]; 31 | } 32 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_request_parser.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace sofa { 10 | namespace pbrpc { 11 | 12 | void RpcRequestParser::RegisteredParsers(std::vector* parsers) 13 | { 14 | parsers->push_back(RpcRequestParserPtr(new BinaryRpcRequestParser())); 15 | parsers->push_back(RpcRequestParserPtr(new HTTPRpcRequestParser())); 16 | } 17 | 18 | } // namespace pbrpc 19 | } // namespace sofa 20 | 21 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 22 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_request_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_RPC_REQUEST_PARSER_H_ 6 | #define _SOFA_PBRPC_RPC_REQUEST_PARSER_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace sofa { 13 | namespace pbrpc { 14 | 15 | class RpcRequestParser; 16 | typedef sofa::pbrpc::shared_ptr RpcRequestParserPtr; 17 | 18 | class RpcRequestParser 19 | { 20 | public: 21 | RpcRequestParser() {} 22 | virtual ~RpcRequestParser(){} 23 | 24 | // Get the parser name. 25 | virtual const char* Name() = 0; 26 | 27 | // Reset the parser to init status. 28 | virtual void Reset() = 0; 29 | 30 | // Check if the parser identifies the magic string. 31 | virtual bool CheckMagicString(const char* magic_string) = 0; 32 | 33 | // Parse received data. 34 | // 35 | // @param buf buffer start address (must be a tran buf) 36 | // @param data_size data size 37 | // @param offset the offset between real data and buffer start address 38 | // @param bytes_consumed bytes used by this request 39 | // 40 | // @retval 1 request data ready 41 | // @retval 0 there are more bytes to be read 42 | // @retval -1 parse request fail 43 | virtual int Parse(const char* buf, int data_size, int offset, int* bytes_consumed) = 0; 44 | 45 | // Get the parsed request data. 46 | // 47 | // Preconditions: 48 | // * Parse() returns 1 49 | virtual RpcRequestPtr GetRequest() = 0; 50 | 51 | public: 52 | // Get all registered parsers. 53 | static void RegisteredParsers(std::vector* parsers); 54 | }; // class RpcRequestParser 55 | 56 | } // namespace pbrpc 57 | } // namespace sofa 58 | 59 | #endif // _SOFA_PBRPC_RPC_REQUEST_PARSER_H_ 60 | 61 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 62 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rpc_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | RpcServer::RpcServer(const RpcServerOptions& options, 15 | EventHandler* handler, 16 | const ProfilingLinker& /*linker*/) 17 | { 18 | touch_boost_error_category(); 19 | _impl.reset(new RpcServerImpl(options, handler)); 20 | } 21 | 22 | RpcServer::~RpcServer() 23 | { 24 | Stop(); 25 | } 26 | 27 | bool RpcServer::Start(const std::string& server_address) 28 | { 29 | return _impl->Start(server_address); 30 | } 31 | 32 | void RpcServer::Stop() 33 | { 34 | _impl->Stop(); 35 | } 36 | 37 | static volatile bool s_quit = false; 38 | static void SignalIntHandler(int /*sig*/) 39 | { 40 | s_quit = true; 41 | } 42 | int RpcServer::Run() 43 | { 44 | signal(SIGINT, SignalIntHandler); 45 | signal(SIGTERM, SignalIntHandler); 46 | while (!s_quit) { 47 | sleep(1); 48 | } 49 | return 0; 50 | } 51 | 52 | RpcServerOptions RpcServer::GetOptions() 53 | { 54 | return _impl->GetOptions(); 55 | } 56 | 57 | void RpcServer::ResetOptions(const RpcServerOptions& options) 58 | { 59 | _impl->ResetOptions(options); 60 | } 61 | 62 | bool RpcServer::RegisterService(google::protobuf::Service* service, bool take_ownership) 63 | { 64 | return _impl->RegisterService(service, take_ownership); 65 | } 66 | 67 | int RpcServer::ServiceCount() 68 | { 69 | return _impl->ServiceCount(); 70 | } 71 | 72 | int RpcServer::ConnectionCount() 73 | { 74 | return _impl->ConnectionCount(); 75 | } 76 | 77 | bool RpcServer::IsListening() 78 | { 79 | return _impl->IsListening(); 80 | } 81 | 82 | bool RpcServer::RegisterWebServlet(const std::string& path, Servlet servlet, bool take_ownership) 83 | { 84 | return _impl->RegisterWebServlet(path, servlet, take_ownership); 85 | } 86 | 87 | Servlet RpcServer::UnregisterWebServlet(const std::string& path) 88 | { 89 | return _impl->UnregisterWebServlet(path); 90 | } 91 | 92 | } // namespace pbrpc 93 | } // namespace sofa 94 | 95 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 96 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/rw_lock.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_RW_LOCK_H_ 6 | #define _SOFA_PBRPC_RW_LOCK_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | 13 | class RWLock 14 | { 15 | public: 16 | RWLock() 17 | { 18 | pthread_rwlock_init(&_lock, NULL); 19 | } 20 | ~RWLock() 21 | { 22 | pthread_rwlock_destroy(&_lock); 23 | } 24 | void lock() 25 | { 26 | pthread_rwlock_wrlock(&_lock); 27 | } 28 | void lock_shared() 29 | { 30 | pthread_rwlock_rdlock(&_lock); 31 | } 32 | void unlock() 33 | { 34 | pthread_rwlock_unlock(&_lock); 35 | } 36 | private: 37 | pthread_rwlock_t _lock; 38 | }; 39 | 40 | class ReadLocker 41 | { 42 | public: 43 | explicit ReadLocker(RWLock* lock) : _lock(lock) 44 | { 45 | _lock->lock_shared(); 46 | } 47 | ~ReadLocker() 48 | { 49 | _lock->unlock(); 50 | } 51 | private: 52 | RWLock* _lock; 53 | }; 54 | class WriteLocker 55 | { 56 | public: 57 | explicit WriteLocker(RWLock* lock) : _lock(lock) 58 | { 59 | _lock->lock(); 60 | } 61 | ~WriteLocker() 62 | { 63 | _lock->unlock(); 64 | } 65 | private: 66 | RWLock* _lock; 67 | }; 68 | 69 | } // namespace pbrpc 70 | } // namespace sofa 71 | 72 | #endif // _SOFA_PBRPC_RW_LOCK_H_ 73 | 74 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 75 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/scoped_locker.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_SCOPED_LOCKER_H_ 6 | #define _SOFA_PBRPC_SCOPED_LOCKER_H_ 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | template 12 | class ScopedLocker 13 | { 14 | public: 15 | explicit ScopedLocker(LockType& lock) 16 | : _lock(&lock) 17 | { 18 | _lock->lock(); 19 | } 20 | 21 | explicit ScopedLocker(LockType* lock) 22 | : _lock(lock) 23 | { 24 | _lock->lock(); 25 | } 26 | 27 | ~ScopedLocker() 28 | { 29 | _lock->unlock(); 30 | } 31 | 32 | private: 33 | LockType* _lock; 34 | }; // class ScopedLocker 35 | 36 | } // namespace pbrpc 37 | } // namespace sofa 38 | 39 | #endif // _SOFA_PBRPC_SCOPED_LOCKER_H_ 40 | 41 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 42 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/simple_rpc_channel_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_SIMPLE_RPC_CHANNEL_IMPL_H_ 6 | #define _SOFA_PBRPC_SIMPLE_RPC_CHANNEL_IMPL_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace sofa { 17 | namespace pbrpc { 18 | 19 | class SimpleRpcChannelImpl : public RpcChannelImpl, 20 | public ::sofa::pbrpc::enable_shared_from_this 21 | { 22 | public: 23 | SimpleRpcChannelImpl(const RpcClientImplPtr& rpc_client_impl, 24 | const std::string& server_address, 25 | const RpcChannelOptions& options); 26 | 27 | virtual ~SimpleRpcChannelImpl(); 28 | 29 | virtual bool Init(); 30 | 31 | virtual void Stop(); 32 | 33 | virtual void CallMethod(const ::google::protobuf::MethodDescriptor* method, 34 | ::google::protobuf::RpcController* controller, 35 | const ::google::protobuf::Message* request, 36 | ::google::protobuf::Message* response, 37 | ::google::protobuf::Closure* done); 38 | 39 | virtual uint32 WaitCount(); 40 | 41 | private: 42 | static void WaitDone(const RpcControllerImplPtr& cntl); 43 | 44 | void DoneCallback(google::protobuf::Closure* done, 45 | const RpcControllerImplPtr& cntl); 46 | 47 | static void MockDoneCallback(RpcControllerImplPtr cntl, 48 | const ::google::protobuf::Message* request, 49 | ::google::protobuf::Message* response); 50 | 51 | private: 52 | RpcClientImplPtr _client_impl; 53 | std::string _server_address; 54 | RpcChannelOptions _options; 55 | 56 | bool _is_mock; 57 | bool _resolve_address_succeed; 58 | RpcEndpoint _remote_endpoint; 59 | 60 | AtomicCounter _wait_count; 61 | 62 | SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(SimpleRpcChannelImpl); 63 | }; // class SimpleRpcChannelImpl 64 | 65 | } // namespace pbrpc 66 | } // namespace sofa 67 | 68 | #endif // _SOFA_PBRPC_SIMPLE_RPC_CHANNEL_IMPL_H_ 69 | 70 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 71 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/bad_weak_ptr.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_BAD_WEAK_PTR_ 14 | #define _SOFA_PBRPC_BAD_WEAK_PTR_ 15 | 16 | #include 17 | 18 | namespace sofa { 19 | namespace pbrpc { 20 | 21 | class bad_weak_ptr: public std::exception 22 | { 23 | public: 24 | virtual char const * what() const throw() 25 | { 26 | return "sofa::pbrpc::bad_weak_ptr"; 27 | } 28 | }; 29 | 30 | } // namespace pbrpc 31 | } // namespace sofa 32 | 33 | #endif // _SOFA_PBRPC_BAD_WEAK_PTR_ 34 | 35 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 36 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/checked_delete.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_CHECKED_DELETE_ 14 | #define _SOFA_PBRPC_SMART_PTR_CHECKED_DELETE_ 15 | 16 | namespace sofa { 17 | namespace pbrpc { 18 | 19 | template 20 | inline void checked_delete(T* px) 21 | { 22 | typedef char type_must_be_complete[sizeof(T) ? 1 : -1 ]; 23 | (void) sizeof(type_must_be_complete); 24 | delete px; 25 | } 26 | 27 | template inline void checked_array_delete(T * x) 28 | { 29 | typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; 30 | (void) sizeof(type_must_be_complete); 31 | delete [] x; 32 | } 33 | 34 | template struct checked_deleter 35 | { 36 | typedef void result_type; 37 | typedef T * argument_type; 38 | 39 | void operator()(T * x) const 40 | { 41 | ::sofa::pbrpc::checked_delete(x); 42 | } 43 | }; 44 | 45 | template struct checked_array_deleter 46 | { 47 | typedef void result_type; 48 | typedef T * argument_type; 49 | 50 | void operator()(T * x) const 51 | { 52 | ::sofa::pbrpc::checked_array_delete(x); 53 | } 54 | }; 55 | 56 | } // namespace pbrpc 57 | } // namespace sofa 58 | 59 | #endif // _SOFA_PBRPC_SMART_PTR_CHECKED_DELETE_ 60 | 61 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 62 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/detail/operator_bool.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | typedef T * (this_type::*unspecified_bool_type)() const; 14 | 15 | operator unspecified_bool_type() const // never throws 16 | { 17 | return px == 0 ? 0: &this_type::get; 18 | } 19 | 20 | // operator! is redundant, but some compilers need it 21 | bool operator! () const // never throws 22 | { 23 | return px == 0; 24 | } 25 | 26 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 27 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/detail/sp_convertible.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SP_CONVERTIBLE_ 14 | #define _SOFA_PBRPC_SMART_PTR_DETAIL_SP_CONVERTIBLE_ 15 | 16 | namespace sofa { 17 | namespace pbrpc { 18 | namespace detail { 19 | 20 | template< class Y, class T > struct sp_convertible 21 | { 22 | typedef char (&yes) [1]; 23 | typedef char (&no) [2]; 24 | 25 | static yes f( T* ); 26 | static no f( ... ); 27 | 28 | enum _vt { value = sizeof( (f)( static_cast(0) ) ) == sizeof(yes) }; 29 | }; 30 | 31 | struct sp_empty 32 | { 33 | }; 34 | 35 | template< bool > struct sp_enable_if_convertible_impl; 36 | 37 | template<> struct sp_enable_if_convertible_impl 38 | { 39 | typedef sp_empty type; 40 | }; 41 | 42 | template<> struct sp_enable_if_convertible_impl 43 | { 44 | }; 45 | 46 | template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value > 47 | { 48 | }; 49 | 50 | } // namespace detail 51 | } // namespace pbrpc 52 | } // namespace sofa 53 | 54 | #endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SP_CONVERTIBLE_ 55 | 56 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 57 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/detail/sp_counted_base.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_ 14 | #define _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_ 15 | 16 | #include 17 | 18 | #endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SP_COUNTED_BASE_ 19 | 20 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 21 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/detail/spinlock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_ 14 | #define _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_ 15 | 16 | #include 17 | 18 | #endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_ 19 | 20 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 21 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/detail/spinlock_pt.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_PT_ 14 | #define _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_PT_ 15 | 16 | #include 17 | 18 | namespace sofa { 19 | namespace pbrpc { 20 | namespace detail { 21 | 22 | class spinlock 23 | { 24 | public: 25 | 26 | pthread_mutex_t v_; 27 | 28 | public: 29 | 30 | bool try_lock() 31 | { 32 | return pthread_mutex_trylock( &v_ ) == 0; 33 | } 34 | 35 | void lock() 36 | { 37 | pthread_mutex_lock( &v_ ); 38 | } 39 | 40 | void unlock() 41 | { 42 | pthread_mutex_unlock( &v_ ); 43 | } 44 | 45 | public: 46 | 47 | class scoped_lock 48 | { 49 | private: 50 | 51 | spinlock & sp_; 52 | 53 | scoped_lock( scoped_lock const & ); 54 | scoped_lock & operator=( scoped_lock const & ); 55 | 56 | public: 57 | 58 | explicit scoped_lock( spinlock & sp ): sp_( sp ) 59 | { 60 | sp.lock(); 61 | } 62 | 63 | ~scoped_lock() 64 | { 65 | sp_.unlock(); 66 | } 67 | }; 68 | }; 69 | 70 | } // namespace detail 71 | } // namespace pbrpc 72 | } // namespace sofa 73 | 74 | #define SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER } 75 | 76 | #endif // _SOFA_PBRPC_SMART_PTR_DETAIL_SPINLOCK_PT_ 77 | 78 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 79 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/enable_shared_from_this.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_ENABLE_SHARED_FROM_THIS_ 14 | #define _SOFA_PBRPC_SMART_PTR_ENABLE_SHARED_FROM_THIS_ 15 | 16 | #include 17 | #include 18 | 19 | namespace sofa { 20 | namespace pbrpc { 21 | 22 | template class enable_shared_from_this 23 | { 24 | protected: 25 | 26 | enable_shared_from_this() 27 | { 28 | } 29 | 30 | enable_shared_from_this(enable_shared_from_this const &) 31 | { 32 | } 33 | 34 | enable_shared_from_this & operator=(enable_shared_from_this const &) 35 | { 36 | return *this; 37 | } 38 | 39 | ~enable_shared_from_this() 40 | { 41 | } 42 | 43 | public: 44 | 45 | shared_ptr shared_from_this() 46 | { 47 | shared_ptr p( weak_this_ ); 48 | assert( p.get() == this ); 49 | return p; 50 | } 51 | 52 | shared_ptr shared_from_this() const 53 | { 54 | shared_ptr p( weak_this_ ); 55 | assert( p.get() == this ); 56 | return p; 57 | } 58 | 59 | public: // actually private, but avoids compiler template friendship issues 60 | 61 | // Note: invoked automatically by shared_ptr; do not call 62 | template void _internal_accept_owner( shared_ptr const * ppx, Y * py ) const 63 | { 64 | if( weak_this_.expired() ) 65 | { 66 | weak_this_ = shared_ptr( *ppx, py ); 67 | } 68 | } 69 | 70 | private: 71 | 72 | mutable weak_ptr weak_this_; 73 | }; 74 | 75 | } // namespace pbrpc 76 | } // namespace sofa 77 | 78 | #endif // _SOFA_PBRPC_SMART_PTR_ENABLE_SHARED_FROM_THIS_ 79 | 80 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 81 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/memory_order.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_MEMORY_ORDER_ 14 | #define _SOFA_PBRPC_SMART_PTR_MEMORY_ORDER_ 15 | 16 | namespace sofa { 17 | namespace pbrpc { 18 | 19 | // 20 | // Enum values are chosen so that code that needs to insert 21 | // a trailing fence for acquire semantics can use a single 22 | // test such as: 23 | // 24 | // if( mo & memory_order_acquire ) { ...fence... } 25 | // 26 | // For leading fences one can use: 27 | // 28 | // if( mo & memory_order_release ) { ...fence... } 29 | // 30 | // Architectures such as Alpha that need a fence on consume 31 | // can use: 32 | // 33 | // if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... } 34 | // 35 | 36 | enum memory_order 37 | { 38 | memory_order_relaxed = 0, 39 | memory_order_acquire = 1, 40 | memory_order_release = 2, 41 | memory_order_acq_rel = 3, // acquire | release 42 | memory_order_seq_cst = 7, // acq_rel | 4 43 | memory_order_consume = 8 44 | }; 45 | 46 | } // namespace pbrpc 47 | } // namespace sofa 48 | 49 | #endif // _SOFA_PBRPC_SMART_PTR_MEMORY_ORDER_ 50 | 51 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 52 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/owner_less.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_OWNER_LESS_ 14 | #define _SOFA_PBRPC_SMART_PTR_OWNER_LESS_ 15 | 16 | #include 17 | 18 | namespace sofa { 19 | namespace pbrpc { 20 | 21 | template class shared_ptr; 22 | template class weak_ptr; 23 | 24 | namespace detail 25 | { 26 | template 27 | struct generic_owner_less : public std::binary_function 28 | { 29 | bool operator()(const T &lhs, const T &rhs) const 30 | { 31 | return lhs.owner_before(rhs); 32 | } 33 | bool operator()(const T &lhs, const U &rhs) const 34 | { 35 | return lhs.owner_before(rhs); 36 | } 37 | bool operator()(const U &lhs, const T &rhs) const 38 | { 39 | return lhs.owner_before(rhs); 40 | } 41 | }; 42 | } // namespace detail 43 | 44 | template struct owner_less; 45 | 46 | template 47 | struct owner_less >: 48 | public detail::generic_owner_less, weak_ptr > 49 | {}; 50 | 51 | template 52 | struct owner_less >: 53 | public detail::generic_owner_less, shared_ptr > 54 | {}; 55 | 56 | } // namespace pbrpc 57 | } // namespace sofa 58 | 59 | #endif // _SOFA_PBRPC_SMART_PTR_OWNER_LESS_ 60 | 61 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 62 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/scoped_array.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_SCOPED_ARRAY_ 14 | #define _SOFA_PBRPC_SMART_PTR_SCOPED_ARRAY_ 15 | 16 | #include 17 | 18 | #include // for std::ptrdiff_t 19 | 20 | namespace sofa { 21 | namespace pbrpc { 22 | 23 | // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to 24 | // is guaranteed, either on destruction of the scoped_array or via an explicit 25 | // reset(). Use shared_array or std::vector if your needs are more complex. 26 | 27 | template class scoped_array // noncopyable 28 | { 29 | private: 30 | 31 | T * px; 32 | 33 | scoped_array(scoped_array const &); 34 | scoped_array & operator=(scoped_array const &); 35 | 36 | typedef scoped_array this_type; 37 | 38 | void operator==( scoped_array const& ) const; 39 | void operator!=( scoped_array const& ) const; 40 | 41 | public: 42 | 43 | typedef T element_type; 44 | 45 | explicit scoped_array( T * p = 0 ) : px( p ) // never throws 46 | { 47 | } 48 | 49 | ~scoped_array() // never throws 50 | { 51 | sofa::pbrpc::checked_array_delete( px ); 52 | } 53 | 54 | void reset(T * p = 0) // never throws 55 | { 56 | this_type(p).swap(*this); 57 | } 58 | 59 | T & operator[](std::ptrdiff_t i) const // never throws 60 | { 61 | return px[i]; 62 | } 63 | 64 | T * get() const // never throws 65 | { 66 | return px; 67 | } 68 | 69 | // implicit conversion to "bool" 70 | #include 71 | 72 | void swap(scoped_array & b) // never throws 73 | { 74 | T * tmp = b.px; 75 | b.px = px; 76 | px = tmp; 77 | } 78 | }; 79 | 80 | template inline void swap(scoped_array & a, scoped_array & b) // never throws 81 | { 82 | a.swap(b); 83 | } 84 | 85 | } // namespace pbrpc 86 | } // namespace sofa 87 | 88 | #endif // _SOFA_PBRPC_SMART_PTR_SCOPED_ARRAY_ 89 | 90 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 91 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/scoped_ptr.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #ifndef _SOFA_PBRPC_SMART_PTR_SCOPED_PTR_ 14 | #define _SOFA_PBRPC_SMART_PTR_SCOPED_PTR_ 15 | 16 | #include 17 | 18 | namespace sofa { 19 | namespace pbrpc { 20 | 21 | // scoped_ptr mimics a built-in pointer except that it guarantees deletion 22 | // of the object pointed to, either on destruction of the scoped_ptr or via 23 | // an explicit reset(). scoped_ptr is a simple solution for simple needs; 24 | // use shared_ptr or std::auto_ptr if your needs are more complex. 25 | 26 | template class scoped_ptr // noncopyable 27 | { 28 | private: 29 | 30 | T * px; 31 | 32 | scoped_ptr(scoped_ptr const &); 33 | scoped_ptr & operator=(scoped_ptr const &); 34 | 35 | typedef scoped_ptr this_type; 36 | 37 | void operator==( scoped_ptr const& ) const; 38 | void operator!=( scoped_ptr const& ) const; 39 | 40 | public: 41 | 42 | typedef T element_type; 43 | 44 | explicit scoped_ptr( T * p = 0 ): px( p ) // never throws 45 | { 46 | } 47 | 48 | ~scoped_ptr() // never throws 49 | { 50 | sofa::pbrpc::checked_delete( px ); 51 | } 52 | 53 | void reset(T * p = 0) // never throws 54 | { 55 | this_type(p).swap(*this); 56 | } 57 | 58 | T & operator*() const // never throws 59 | { 60 | return *px; 61 | } 62 | 63 | T * operator->() const // never throws 64 | { 65 | return px; 66 | } 67 | 68 | T * get() const // never throws 69 | { 70 | return px; 71 | } 72 | 73 | // implicit conversion to "bool" 74 | #include 75 | 76 | void swap(scoped_ptr & b) // never throws 77 | { 78 | T * tmp = b.px; 79 | b.px = px; 80 | px = tmp; 81 | } 82 | }; 83 | 84 | template inline void swap(scoped_ptr & a, scoped_ptr & b) // never throws 85 | { 86 | a.swap(b); 87 | } 88 | 89 | // get_pointer(p) is a generic way to say p.get() 90 | 91 | template inline T * get_pointer(scoped_ptr const & p) 92 | { 93 | return p.get(); 94 | } 95 | 96 | } // namespace pbrpc 97 | } // namespace sofa 98 | 99 | #endif // _SOFA_PBRPC_SMART_PTR_SCOPED_PTR_ 100 | 101 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 102 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/smart_ptr/smart_ptr.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is modified from boost. 6 | // 7 | // Copyright Beman Dawes 2002, 2006 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // See library home page at http://www.boost.org/libs/system 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 21 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/spin_lock.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_SPIN_LOCK_H_ 6 | #define _SOFA_PBRPC_SPIN_LOCK_H_ 7 | 8 | #ifdef __APPLE__ 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | class SpinLock 15 | { 16 | public: 17 | SpinLock(): _lock(0) { } 18 | ~SpinLock() { } 19 | void lock() { OSSpinLockLock(&_lock); } 20 | bool try_lock() { return OSSpinLockTry(&_lock); } 21 | void unlock() { OSSpinLockUnlock(&_lock); } 22 | 23 | private: 24 | OSSpinLock _lock; 25 | }; // class SpinLock 26 | 27 | } 28 | } 29 | 30 | #else 31 | 32 | #include 33 | 34 | namespace sofa { 35 | namespace pbrpc { 36 | 37 | class SpinLock 38 | { 39 | public: 40 | SpinLock() { pthread_spin_init(&_lock, 0); } 41 | ~SpinLock() { pthread_spin_destroy(&_lock); } 42 | void lock() { pthread_spin_lock(&_lock); } 43 | bool try_lock() { return pthread_spin_trylock(&_lock) == 0; } 44 | void unlock() { pthread_spin_unlock(&_lock); } 45 | 46 | private: 47 | pthread_spinlock_t _lock; 48 | }; // class SpinLock 49 | 50 | } // namespace pbrpc 51 | } // namespace sofa 52 | #endif 53 | 54 | #endif // _SOFA_PBRPC_SPIN_LOCK_H_ 55 | 56 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 57 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/thread_group.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | ThreadGroup::ThreadGroup(int thread_num) 12 | { 13 | _imp.reset(new ThreadGroupImpl(thread_num)); 14 | _imp->start(); 15 | } 16 | 17 | ThreadGroup::~ThreadGroup() 18 | { 19 | _imp->stop(); 20 | _imp.reset(); 21 | } 22 | 23 | int ThreadGroup::thread_num() const 24 | { 25 | return _imp->thread_num(); 26 | } 27 | 28 | void ThreadGroup::dispatch(google::protobuf::Closure* handle) 29 | { 30 | _imp->dispatch(handle); 31 | } 32 | 33 | void ThreadGroup::post(google::protobuf::Closure* handle) 34 | { 35 | _imp->post(handle); 36 | } 37 | 38 | void ThreadGroup::dispatch(ExtClosure* handle) 39 | { 40 | _imp->dispatch(handle); 41 | } 42 | 43 | void ThreadGroup::post(ExtClosure* handle) 44 | { 45 | _imp->post(handle); 46 | } 47 | 48 | } // namespace pbrpc 49 | } // namespace sofa 50 | 51 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 52 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/thread_group.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_THREAD_GROUP_H_ 6 | #define _SOFA_PBRPC_THREAD_GROUP_H_ 7 | 8 | #include 9 | #include 10 | 11 | namespace sofa { 12 | namespace pbrpc { 13 | 14 | // Defined in this file. 15 | class ThreadGroup; 16 | typedef sofa::pbrpc::shared_ptr ThreadGroupPtr; 17 | 18 | // Defined in other files. 19 | class ThreadGroupImpl; 20 | 21 | class ThreadGroup 22 | { 23 | public: 24 | // Constructor. User should specify the "thread_num", which can not be changed 25 | // afterwards. All the threads will start running after contruct done. 26 | ThreadGroup(int thread_num); 27 | 28 | // Destructor. It will join all threads, so user must ensure that all threads 29 | // will exit eventually. 30 | ~ThreadGroup(); 31 | 32 | // Get the number of threads in this thread group. 33 | int thread_num() const; 34 | 35 | // Request the thread group to invoke the given handler. 36 | // The handler may be executed inside this function if the guarantee can be met. 37 | // The "handler" should be a self delete closure, which can be created through 38 | // NewClosure(). 39 | void dispatch(google::protobuf::Closure* handler); 40 | 41 | // Request the thread group to invoke the given handler and return immediately. 42 | // It guarantees that the handler will not be called from inside this function. 43 | // The "handler" should be a self delete closure, which can be created through 44 | // NewClosure(). 45 | void post(google::protobuf::Closure* handler); 46 | 47 | // Request the thread group to invoke the given handler. 48 | // The handler may be executed inside this function if the guarantee can be met. 49 | // The "handler" should be a self delete closure, which can be created through 50 | // NewExtClosure(). 51 | void dispatch(ExtClosure* handler); 52 | 53 | // Request the thread group to invoke the given handler and return immediately. 54 | // It guarantees that the handler will not be called from inside this function. 55 | // The "handler" should be a self delete closure, which can be created through 56 | // NewExtClosure(). 57 | void post(ExtClosure* handler); 58 | 59 | private: 60 | sofa::pbrpc::shared_ptr _imp; 61 | 62 | SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(ThreadGroup); 63 | }; 64 | 65 | } // namespace pbrpc 66 | } // namespace sofa 67 | 68 | #endif // _SOFA_PBRPC_THREAD_GROUP_H_ 69 | 70 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 71 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/timeout_manager.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | namespace sofa { 9 | namespace pbrpc { 10 | 11 | TimeoutManager::TimeoutManager() 12 | { 13 | _imp.reset(new TimeoutManagerImpl()); 14 | _imp->start(); 15 | } 16 | 17 | TimeoutManager::~TimeoutManager() 18 | { 19 | _imp->stop(); 20 | _imp.reset(); 21 | } 22 | 23 | void TimeoutManager::clear() 24 | { 25 | _imp->clear(); 26 | } 27 | 28 | TimeoutManager::Id TimeoutManager::add(int64 interval, Callback* callback) 29 | { 30 | return _imp->add(interval, callback); 31 | } 32 | 33 | TimeoutManager::Id TimeoutManager::add_repeating(int64 interval, Callback* callback) 34 | { 35 | return _imp->add_repeating(interval, callback); 36 | } 37 | 38 | bool TimeoutManager::erase(Id id) 39 | { 40 | return _imp->erase(id); 41 | } 42 | 43 | } // namespace pbrpc 44 | } // namespace sofa 45 | 46 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 47 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/timer_worker.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_TIMER_WORKER_H_ 6 | #define _SOFA_PBRPC_TIMER_WORKER_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | 13 | class TimerWorker : public sofa::pbrpc::enable_shared_from_this 14 | { 15 | public: 16 | typedef boost::function WorkRoutine; 17 | 18 | public: 19 | TimerWorker(IOService& io_service) 20 | : _io_service(io_service) 21 | , _is_running(false) 22 | , _time_duration(time_duration_seconds(1)) 23 | , _work_routine(NULL) 24 | , _timer(io_service) 25 | , _strand(io_service) 26 | {} 27 | 28 | ~TimerWorker() 29 | { 30 | SOFA_PBRPC_FUNCTION_TRACE; 31 | stop(); 32 | } 33 | 34 | bool is_running() 35 | { 36 | return _is_running; 37 | } 38 | 39 | void set_time_duration(const TimeDuration& time_duration) 40 | { 41 | _time_duration = time_duration; 42 | } 43 | 44 | void set_work_routine(const WorkRoutine& work_routine) 45 | { 46 | _work_routine = work_routine; 47 | } 48 | 49 | void start() 50 | { 51 | if (_is_running) return; 52 | _is_running = true; 53 | 54 | ScopedLocker _(_timer_lock); 55 | _timer.expires_from_now(_time_duration); 56 | _timer.async_wait(_strand.wrap(boost::bind( 57 | &TimerWorker::on_timeout, shared_from_this(), _1))); 58 | } 59 | 60 | void stop() 61 | { 62 | if (!_is_running) return; 63 | _is_running = false; 64 | 65 | ScopedLocker _(_timer_lock); 66 | _timer.cancel(); 67 | } 68 | 69 | private: 70 | void on_timeout(const boost::system::error_code& ec) 71 | { 72 | if (_is_running) 73 | { 74 | PTime now = ptime_now(); 75 | 76 | if (ec != boost::asio::error::operation_aborted && _work_routine) 77 | { 78 | _work_routine(now); 79 | } 80 | 81 | ScopedLocker _(_timer_lock); 82 | _timer.expires_at(now + _time_duration); 83 | _timer.async_wait(_strand.wrap(boost::bind( 84 | &TimerWorker::on_timeout, shared_from_this(), _1))); 85 | } 86 | } 87 | 88 | private: 89 | IOService& _io_service; 90 | volatile bool _is_running; 91 | 92 | TimeDuration _time_duration; 93 | WorkRoutine _work_routine; 94 | 95 | IOServiceTimer _timer; 96 | MutexLock _timer_lock; 97 | IOServiceStrand _strand; 98 | 99 | SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(TimerWorker); 100 | }; // class TimerWorker 101 | 102 | } // namespace pbrpc 103 | } // namespace sofa 104 | 105 | #endif // _SOFA_PBRPC_TIMER_WORKER_H_ 106 | 107 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 108 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/wait_event.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_WAIT_EVENT_H_ 6 | #define _SOFA_PBRPC_WAIT_EVENT_H_ 7 | 8 | #include 9 | 10 | namespace sofa { 11 | namespace pbrpc { 12 | 13 | class WaitEvent 14 | { 15 | public: 16 | WaitEvent() : _signaled(false) 17 | { 18 | pthread_mutex_init(&_lock, NULL); 19 | pthread_cond_init(&_cond, NULL); 20 | } 21 | ~WaitEvent() 22 | { 23 | pthread_mutex_destroy(&_lock); 24 | pthread_cond_destroy(&_cond); 25 | } 26 | 27 | void Wait() 28 | { 29 | pthread_mutex_lock(&_lock); 30 | while (!_signaled) 31 | { 32 | pthread_cond_wait(&_cond, &_lock); 33 | } 34 | _signaled = false; 35 | pthread_mutex_unlock(&_lock); 36 | } 37 | 38 | void Signal() 39 | { 40 | pthread_mutex_lock(&_lock); 41 | _signaled = true; 42 | pthread_cond_signal(&_cond); 43 | pthread_mutex_unlock(&_lock); 44 | } 45 | 46 | private: 47 | pthread_mutex_t _lock; 48 | pthread_cond_t _cond; 49 | bool _signaled; 50 | }; 51 | 52 | } // namespace pbrpc 53 | } // namespace sofa 54 | 55 | #endif // _SOFA_PBRPC_WAIT_EVENT_H_ 56 | 57 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 58 | -------------------------------------------------------------------------------- /src/sofa/pbrpc/web_service.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef _SOFA_PBRPC_WEB_SERVICE_H_ 6 | #define _SOFA_PBRPC_WEB_SERVICE_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace sofa { 13 | namespace pbrpc { 14 | 15 | struct HTTPRequest; 16 | struct HTTPResponse; 17 | typedef ExtClosure* Servlet; 18 | 19 | typedef std::map > ServletMap; 20 | typedef sofa::pbrpc::shared_ptr ServletMapPtr; 21 | 22 | class WebService 23 | { 24 | public: 25 | WebService(const ServicePoolWPtr& service_pool); 26 | ~WebService(); 27 | 28 | void Init(); 29 | 30 | bool RegisterServlet(const std::string& path, Servlet servlet, bool take_ownership = true); 31 | 32 | Servlet UnregisterServlet(const std::string& path); 33 | 34 | bool RoutePage( 35 | const RpcRequestPtr& rpc_request, 36 | const RpcServerStreamWPtr& server_stream); 37 | 38 | private: 39 | Servlet FindServlet(const std::string& path); 40 | 41 | bool DefaultHome(const HTTPRequest& request, HTTPResponse& response); 42 | 43 | bool DefaultOptions(const HTTPRequest& request, HTTPResponse& response); 44 | 45 | bool DefaultStatus(const HTTPRequest& request, HTTPResponse& response); 46 | 47 | bool DefaultServices(const HTTPRequest& request, HTTPResponse& response); 48 | 49 | bool DefaultService(const HTTPRequest& request, HTTPResponse& response); 50 | 51 | bool DefaultProfiling(const HTTPRequest& request, HTTPResponse& response); 52 | 53 | static void PageHeader(std::ostream& out); 54 | 55 | static void PageFooter(std::ostream& out); 56 | 57 | void ServerBrief(std::ostream& out, 58 | const HTTPRequest& request); 59 | 60 | void ServerOptions(std::ostream& out); 61 | 62 | void ServerStatus(std::ostream& out); 63 | 64 | void ServiceList(std::ostream& out); 65 | 66 | static void MethodList(std::ostream& out, 67 | ServiceBoard* svc_board); 68 | 69 | static void ErrorPage(std::ostream& out, 70 | const std::string& reason); 71 | 72 | void ServletList(std::ostream& out); 73 | 74 | ServletMapPtr GetServletPtr(); 75 | 76 | private: 77 | ServicePoolPtr _service_pool; 78 | 79 | FastLock _servlet_map_lock; 80 | ServletMapPtr _servlet_map; 81 | 82 | Servlet _default_home; 83 | Servlet _default_options; 84 | Servlet _default_status; 85 | Servlet _default_services; 86 | Servlet _default_service; 87 | Servlet _default_profiling; 88 | 89 | SOFA_PBRPC_DISALLOW_EVIL_CONSTRUCTORS(WebService); 90 | }; 91 | 92 | } // namespace pbrpc 93 | } // namespace sofa 94 | 95 | #endif // _SOFA_PBRPC_WEB_SERVICE_H_ 96 | -------------------------------------------------------------------------------- /test/kill_test/echo_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "echo_service.pb.h" 11 | 12 | static sofa::pbrpc::AtomicCounter s_succeed_count(0); 13 | 14 | class EchoServerImpl : public sofa::pbrpc::test::EchoServer 15 | { 16 | public: 17 | EchoServerImpl() {} 18 | virtual ~EchoServerImpl() {} 19 | 20 | private: 21 | virtual void Echo(google::protobuf::RpcController* controller, 22 | const sofa::pbrpc::test::EchoRequest* request, 23 | sofa::pbrpc::test::EchoResponse* response, 24 | google::protobuf::Closure* done) 25 | { 26 | if (controller->IsCanceled()) 27 | done->Run(); 28 | response->set_message(request->message()); 29 | ++s_succeed_count; 30 | done->Run(); 31 | } 32 | }; 33 | 34 | volatile bool g_quit = false; 35 | static void SignalIntHandler(int /* sig */) 36 | { 37 | g_quit = true; 38 | } 39 | 40 | int main(int argc, char** argv) 41 | { 42 | if (argc < 3) 43 | { 44 | fprintf(stderr, "Usage: %s \n", argv[0]); 45 | return EXIT_FAILURE; 46 | } 47 | std::string address = argv[1] + std::string(":") + argv[2]; 48 | 49 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 50 | // Define an rpc server. 51 | sofa::pbrpc::RpcServerOptions options; 52 | options.max_throughput_in = 30; 53 | options.max_throughput_out = 30; 54 | options.keep_alive_time = 5; 55 | sofa::pbrpc::RpcServer rpc_server(options); 56 | 57 | // Start rpc server. 58 | if (!rpc_server.Start(address)) { 59 | SLOG(ERROR, "start server failed"); 60 | return EXIT_FAILURE; 61 | } 62 | 63 | sofa::pbrpc::test::EchoServer* echo_service = new EchoServerImpl(); 64 | if (!rpc_server.RegisterService(echo_service)) { 65 | SLOG(ERROR, "export service failed"); 66 | return EXIT_FAILURE; 67 | } 68 | 69 | signal(SIGINT, SignalIntHandler); 70 | signal(SIGTERM, SignalIntHandler); 71 | 72 | long elapsed_time_us; 73 | long print_interval_us = 1000000; 74 | struct timeval tv1, tv2; 75 | struct timezone tz1, tz2; 76 | gettimeofday(&tv1, &tz1); 77 | while (!g_quit) { 78 | usleep(100000); 79 | 80 | gettimeofday(&tv2, &tz2); 81 | elapsed_time_us = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); 82 | if (elapsed_time_us >= print_interval_us) { 83 | SLOG(NOTICE, "succeed_count=%lld", 84 | static_cast(s_succeed_count)); 85 | gettimeofday(&tv1, &tz1); 86 | } 87 | } 88 | 89 | return EXIT_SUCCESS; 90 | } 91 | 92 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 93 | -------------------------------------------------------------------------------- /test/kill_test/echo_service.proto: -------------------------------------------------------------------------------- 1 | package sofa.pbrpc.test; 2 | 3 | option cc_generic_services = true; 4 | 5 | message EchoRequest { 6 | required string message = 1; 7 | } 8 | 9 | message EchoResponse { 10 | required string message = 1; 11 | } 12 | 13 | service EchoServer { 14 | rpc Echo(EchoRequest) returns(EchoResponse); 15 | } 16 | -------------------------------------------------------------------------------- /test/kill_test/kill_client_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ############################################# 4 | HOST=$HOSTNAME 5 | PORT=12346 6 | SERVER=echo_server 7 | CLIENT=client_parallel 8 | CLIENT_LOG=__kill_client.client.tmp.log 9 | SERVER_LOG=__kill_client.server.log 10 | ############################################# 11 | 12 | if ! [ -f "$SERVER" ] || ! [ -f "$CLIENT" ] 13 | then 14 | echo "binary not generated, to make!" 15 | exit 1 16 | fi 17 | 18 | function at_exit() 19 | { 20 | killall $SERVER &>/dev/null 21 | killall $CLIENT &>/dev/null 22 | exit 1 23 | } 24 | 25 | trap 'at_exit' INT QUIT 26 | killall $SERVER &>/dev/null 27 | killall $CLIENT &>/dev/null 28 | 29 | echo "./$SERVER $HOST $PORT &>$SERVER_LOG &" 30 | ./$SERVER $HOST $PORT &>$SERVER_LOG & 31 | sleep 1 32 | 33 | i=0 34 | while true 35 | do 36 | echo "------------ [$i] --------------" 37 | date 38 | 39 | SIZE=$(((RANDOM % 3) * (RANDOM % 10) * 1024 + RANDOM % 1024)) 40 | GRACE_FLAG=$((RANDOM % 2)) 41 | if [ $GRACE_FLAG == 1 ]; then 42 | IS_GRACE="true" 43 | else 44 | IS_GRACE="false" 45 | fi 46 | echo "./$CLIENT $HOST $PORT $SIZE $IS_GRACE &>$CLIENT_LOG &" 47 | ./$CLIENT $HOST $PORT $SIZE $IS_GRACE &>$CLIENT_LOG & 48 | PID=$! 49 | 50 | SLEEP_TIME=$((RANDOM % 3 + 1)) 51 | echo "Sleep $SLEEP_TIME" 52 | sleep $SLEEP_TIME 53 | 54 | kill $PID &>/dev/null 55 | wait $PID 56 | 57 | if ls core* 2>/dev/null; then 58 | at_exit 59 | fi 60 | if [ $GRACE_FLAG == 1 ]; then 61 | if grep ERROR $CLIENT_LOG; then 62 | at_exit 63 | fi 64 | fi 65 | 66 | grep Succeed $CLIENT_LOG 67 | rm $CLIENT_LOG &>/dev/null 68 | echo "Done" 69 | echo 70 | 71 | i=$((i+1)) 72 | sleep 1 73 | done 74 | 75 | at_exit 76 | 77 | -------------------------------------------------------------------------------- /test/kill_test/kill_server_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ############################################# 4 | HOST=$HOSTNAME 5 | PORT=12345 6 | SERVER=echo_server 7 | CLIENT=client_parallel 8 | SERVER_LOG=__kill_server.server.tmp.log 9 | CLIENT_LOG=__kill_server.client.tmp.log 10 | ############################################# 11 | 12 | if ! [ -f "$SERVER" ] || ! [ -f "$CLIENT" ] 13 | then 14 | echo "binary not generated, to make!" 15 | exit 1 16 | fi 17 | 18 | function at_exit() 19 | { 20 | killall $SERVER &>/dev/null 21 | killall $CLIENT &>/dev/null 22 | exit 1 23 | } 24 | 25 | trap 'at_exit' INT QUIT 26 | killall $SERVER &>/dev/null 27 | killall $CLIENT &>/dev/null 28 | 29 | i=0 30 | while true 31 | do 32 | echo "------------ [$i] --------------" 33 | date 34 | 35 | echo "./$SERVER $HOST $PORT &>$SERVER_LOG &" 36 | ./$SERVER $HOST $PORT &>$SERVER_LOG & 37 | SERVER_PID=$! 38 | sleep 1 39 | 40 | SIZE=$(((RANDOM % 3) * (RANDOM % 10) * 1024 + RANDOM % 1024)) 41 | echo "./$CLIENT $HOST $PORT $SIZE false &>$CLIENT_LOG &" 42 | ./$CLIENT $HOST $PORT $SIZE false &>$CLIENT_LOG & 43 | CLIENT_PID=$! 44 | 45 | SLEEP_TIME=$((RANDOM % 3 + 2)) 46 | echo "Sleep $SLEEP_TIME" 47 | sleep $SLEEP_TIME 48 | 49 | kill $SERVER_PID &>/dev/null 50 | wait $SERVER_PID 51 | wait $CLIENT_PID 52 | 53 | if ls core* 2>/dev/null; then 54 | at_exit 55 | fi 56 | 57 | grep 'Succeed' $CLIENT_LOG 58 | rm $CLIENT_LOG $SERVER_LOG &>/dev/null 59 | echo "Done" 60 | echo 61 | 62 | i=$((i+1)) 63 | sleep 1 64 | done 65 | 66 | at_exit 67 | 68 | -------------------------------------------------------------------------------- /test/perf_test/echo_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "echo_service.pb.h" 11 | 12 | static sofa::pbrpc::AtomicCounter s_succeed_count(0); 13 | 14 | class EchoServerImpl : public sofa::pbrpc::test::EchoServer 15 | { 16 | public: 17 | EchoServerImpl() {} 18 | virtual ~EchoServerImpl() {} 19 | 20 | private: 21 | virtual void Echo(google::protobuf::RpcController* /* controller */, 22 | const sofa::pbrpc::test::EchoRequest* request, 23 | sofa::pbrpc::test::EchoResponse* response, 24 | google::protobuf::Closure* done) 25 | { 26 | response->set_message(request->message()); 27 | ++s_succeed_count; 28 | done->Run(); 29 | } 30 | }; 31 | 32 | volatile bool g_quit = false; 33 | 34 | static void SignalIntHandler(int /* sig */) 35 | { 36 | g_quit = true; 37 | } 38 | 39 | int main(int argc, char** argv) 40 | { 41 | if (argc < 4) 42 | { 43 | fprintf(stderr, "Usage: %s \n", argv[0]); 44 | return EXIT_FAILURE; 45 | } 46 | std::string address = argv[1] + std::string(":") + argv[2]; 47 | int thread_num = atoi(argv[3]); 48 | 49 | SOFA_PBRPC_SET_LOG_LEVEL(NOTICE); 50 | 51 | // Define an rpc server. 52 | sofa::pbrpc::RpcServerOptions options; 53 | options.work_thread_num = thread_num; 54 | options.max_pending_buffer_size = 100; 55 | sofa::pbrpc::RpcServer rpc_server(options); 56 | 57 | // Start rpc server. 58 | if (!rpc_server.Start(address)) { 59 | SLOG(ERROR, "start server failed"); 60 | return EXIT_FAILURE; 61 | } 62 | 63 | sofa::pbrpc::test::EchoServer* echo_service = new EchoServerImpl(); 64 | if (!rpc_server.RegisterService(echo_service)) { 65 | SLOG(ERROR, "export service failed"); 66 | return EXIT_FAILURE; 67 | } 68 | 69 | signal(SIGINT, SignalIntHandler); 70 | signal(SIGTERM, SignalIntHandler); 71 | 72 | long elapsed_time_us; 73 | long print_interval_us = 1000000; 74 | struct timeval tv1, tv2; 75 | struct timezone tz1, tz2; 76 | gettimeofday(&tv1, &tz1); 77 | long last_succeed_count = 0; 78 | while (!g_quit) { 79 | usleep(100000); 80 | 81 | gettimeofday(&tv2, &tz2); 82 | elapsed_time_us = (tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec); 83 | if (elapsed_time_us >= print_interval_us) { 84 | long curr_succeed_count = static_cast(s_succeed_count); 85 | SLOG(NOTICE, "QPS=%ld", curr_succeed_count - last_succeed_count); 86 | last_succeed_count = curr_succeed_count; 87 | gettimeofday(&tv1, &tz1); 88 | } 89 | } 90 | 91 | return EXIT_SUCCESS; 92 | } 93 | 94 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 95 | -------------------------------------------------------------------------------- /test/perf_test/echo_service.proto: -------------------------------------------------------------------------------- 1 | import "sofa/pbrpc/rpc_option.proto"; 2 | 3 | package sofa.pbrpc.test; 4 | 5 | option cc_generic_services = true; 6 | 7 | message EchoRequest { 8 | required string message = 1; 9 | } 10 | 11 | message EchoResponse { 12 | required string message = 1; 13 | } 14 | 15 | service EchoServer { 16 | rpc Echo(EchoRequest) returns(EchoResponse) { 17 | option (sofa.pbrpc.request_compress_type) = CompressTypeNone; 18 | option (sofa.pbrpc.response_compress_type) = CompressTypeNone; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/perf_test/test_delay.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################# 4 | HOST=$HOSTNAME 5 | PORT=12345 6 | THREAD_NUM=8 7 | SERVER=echo_server 8 | CLIENT=client_serial 9 | SERVER_LOG=__test_delay.server.log 10 | CLIENT_LOG=__test_delay.client.log 11 | ############################################# 12 | 13 | if ! [ -f "$SERVER" ] || ! [ -f "$CLIENT" ] 14 | then 15 | echo "binary not generated, to make!" 16 | exit 1 17 | fi 18 | 19 | function at_exit() 20 | { 21 | killall $SERVER &>/dev/null 22 | killall $CLIENT &>/dev/null 23 | rm __test_delay.*.log 24 | exit 1 25 | } 26 | 27 | trap 'at_exit' INT QUIT 28 | killall $SERVER &>/dev/null 29 | killall $CLIENT &>/dev/null 30 | 31 | echo "./$SERVER $HOST $PORT $THREAD_NUM &>$SERVER_LOG &" 32 | ./$SERVER $HOST $PORT $THREAD_NUM &>$SERVER_LOG & 33 | sleep 1 34 | if 35 | grep "ERROR" $SERVER_LOG 36 | then 37 | at_exit 38 | fi 39 | 40 | for i in "100 0.1K" "900 1K-" "1100 1K+" "10000 10K" "100000 100K" "1000000 1M" "10000000 10M"; do 41 | arr=($i) 42 | num=${arr[0]} 43 | str=${arr[1]} 44 | echo 45 | echo "============= test $str data ==============" 46 | echo "./$CLIENT $HOST $PORT $num &>$CLIENT_LOG &" 47 | ./$CLIENT $HOST $PORT $num &>$CLIENT_LOG & 48 | PID=$! 49 | SLEEP=5 50 | echo "sleep $SLEEP" 51 | sleep $SLEEP 52 | grep -o -a 'elapsed time in us: [0-9]*$' $CLIENT_LOG \ 53 | | awk 'BEGIN{sum=0;num=0}{if(NR > 10){sum+=$5;++num;}}END{ \ 54 | print "Succeed count: " num; \ 55 | print "Average elapsed time per request: " (sum/num) "us";}' 56 | kill $PID 57 | sleep 1 58 | done 59 | 60 | echo 61 | at_exit 62 | 63 | -------------------------------------------------------------------------------- /test/perf_test/test_multi_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################# 4 | HOST=$HOSTNAME 5 | PORT_LIST="12345 12346 12347" 6 | THREAD_NUM=8 7 | SERVER=echo_server 8 | CLIENT=client_multi_server 9 | ############################################# 10 | 11 | if ! [ -f "$SERVER" ] || ! [ -f "$CLIENT" ] 12 | then 13 | echo "binary not generated, to make!" 14 | exit 1 15 | fi 16 | 17 | function at_exit() 18 | { 19 | killall $SERVER &>/dev/null 20 | killall $CLIENT &>/dev/null 21 | rm __test_multi_server.*.log 22 | exit 1 23 | } 24 | 25 | trap 'at_exit' INT QUIT 26 | killall $SERVER &>/dev/null 27 | killall $CLIENT &>/dev/null 28 | 29 | i=0 30 | for PORT in $PORT_LIST 31 | do 32 | SERVER_LOG=__test_multi_server.server.$i.log 33 | echo "./$SERVER $HOST $PORT $THREAD_NUM &>$SERVER_LOG &" 34 | ./$SERVER $HOST $PORT $THREAD_NUM &>$SERVER_LOG & 35 | sleep 1 36 | if 37 | grep "ERROR" $SERVER_LOG 38 | then 39 | at_exit 40 | fi 41 | done 42 | 43 | CLIENT_PARAM="" 44 | for PORT in $PORT_LIST 45 | do 46 | CLIENT_PARAM="$CLIENT_PARAM $HOST:$PORT" 47 | done 48 | 49 | echo "./$CLIENT $CLIENT_PARAM" 50 | ./$CLIENT $CLIENT_PARAM 51 | 52 | at_exit 53 | 54 | -------------------------------------------------------------------------------- /test/perf_test/test_qps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################# 4 | HOST=$HOSTNAME 5 | PORT=12345 6 | THREAD_NUM=8 7 | CLIENT_COUNT=5 8 | SERVER=echo_server 9 | CLIENT=client_parallel 10 | SERVER_LOG=__test_qps.server.log 11 | ############################################# 12 | 13 | if ! [ -f "$SERVER" ] || ! [ -f "$CLIENT" ] 14 | then 15 | echo "binary not generated, to make!" 16 | exit 1 17 | fi 18 | 19 | function at_exit() 20 | { 21 | killall $SERVER &>/dev/null 22 | killall $CLIENT &>/dev/null 23 | rm __test_qps.*.log 24 | exit 1 25 | } 26 | 27 | trap 'at_exit' INT QUIT 28 | killall $SERVER &>/dev/null 29 | killall $CLIENT &>/dev/null 30 | 31 | echo "./$SERVER $HOST $PORT $THREAD_NUM &>$SERVER_LOG &" 32 | ./$SERVER $HOST $PORT $THREAD_NUM &>$SERVER_LOG & 33 | sleep 1 34 | if 35 | grep "ERROR" $SERVER_LOG 36 | then 37 | at_exit 38 | fi 39 | 40 | i=0 41 | while [ $i -lt $CLIENT_COUNT ] 42 | do 43 | CLIENT_LOG=__test_qps.client.$i.log 44 | echo "./$CLIENT $HOST $PORT 1 &>$CLIENT_LOG &" 45 | ./$CLIENT $HOST $PORT 1 &>$CLIENT_LOG & 46 | sleep 1 47 | i=$((i+1)) 48 | done 49 | 50 | echo "tail -f $SERVER_LOG" 51 | tail -f $SERVER_LOG 52 | 53 | at_exit 54 | 55 | -------------------------------------------------------------------------------- /unit-test/BUILD: -------------------------------------------------------------------------------- 1 | load("@protobuf//:protobuf.bzl", "cc_proto_library") 2 | 3 | cc_proto_library( 4 | name = "test_data", 5 | srcs = [ 6 | "test_data.proto", 7 | ], 8 | include = ".", 9 | default_runtime = "@protobuf//:protobuf", 10 | protoc = "@protobuf//:protoc", 11 | deps = [ 12 | "//:cc_protos", 13 | ], 14 | ) 15 | 16 | cc_binary( 17 | name = "test_atomic", 18 | srcs = ["test_atomic.cc"], 19 | deps = [ 20 | "//:sofa-pbrpc", 21 | ], 22 | visibility = ["//main:__pkg__"], 23 | ) 24 | 25 | cc_library( 26 | name = "test_buffer-deps", 27 | hdrs = [ 28 | "//:src/sofa/pbrpc/buffer.cc", 29 | ], 30 | deps = [ 31 | "//:sofa-pbrpc" 32 | ], 33 | visibility = ["//main:__pkg__"], 34 | ) 35 | 36 | cc_binary( 37 | name = "test_buffer", 38 | srcs = ["test_buffer.cc"], 39 | deps = [ 40 | ":test_data", 41 | "//:sofa-pbrpc", 42 | ":test_buffer-deps", 43 | ], 44 | includes = ["src"], 45 | copts = [ 46 | "-fno-access-control", 47 | ], 48 | visibility = ["//main:__pkg__"], 49 | ) 50 | 51 | cc_binary( 52 | name = "test_closure", 53 | srcs = ["test_closure.cc"], 54 | deps = [ 55 | "//:sofa-pbrpc" 56 | ], 57 | visibility = ["//main:__pkg__"], 58 | ) 59 | 60 | cc_binary( 61 | name = "test_common", 62 | srcs = ["test_common.cc"], 63 | deps = [ 64 | "//:sofa-pbrpc" 65 | ], 66 | copts = [ 67 | "-DBAZEL_BUILD" 68 | ], 69 | visibility = ["//main:__pkg__"], 70 | ) 71 | 72 | cc_binary( 73 | name = "test_epoll_support", 74 | srcs = ["test_epoll_support.cc"], 75 | deps = [ 76 | "//:sofa-pbrpc" 77 | ], 78 | visibility = ["//main:__pkg__"], 79 | ) 80 | 81 | cc_binary( 82 | name = "test_ext_closure", 83 | srcs = ["test_ext_closure.cc"], 84 | deps = [ 85 | "//:sofa-pbrpc" 86 | ], 87 | visibility = ["//main:__pkg__"], 88 | ) 89 | 90 | cc_binary( 91 | name = "test_io_service_pool", 92 | srcs = ["test_io_service_pool.cc"], 93 | deps = [ 94 | "//:sofa-pbrpc" 95 | ], 96 | visibility = ["//main:__pkg__"], 97 | ) 98 | 99 | cc_binary( 100 | name = "test_thread_group", 101 | srcs = ["test_thread_group.cc"], 102 | deps = [ 103 | "//:sofa-pbrpc" 104 | ], 105 | visibility = ["//main:__pkg__"], 106 | ) 107 | 108 | cc_binary( 109 | name = "test_timeout_manager", 110 | srcs = ["test_timeout_manager.cc"], 111 | deps = [ 112 | "//:sofa-pbrpc" 113 | ], 114 | visibility = ["//main:__pkg__"], 115 | ) 116 | 117 | cc_binary( 118 | name = "test_tran_buf_pool", 119 | srcs = ["test_tran_buf_pool.cc"], 120 | deps = [ 121 | "//:sofa-pbrpc" 122 | ], 123 | visibility = ["//main:__pkg__"], 124 | ) 125 | 126 | cc_binary( 127 | name = "test_web_service", 128 | srcs = ["test_web_service.cc"], 129 | deps = [ 130 | "//:sofa-pbrpc" 131 | ], 132 | copts = [ 133 | "-fno-access-control", 134 | ], 135 | visibility = ["//main:__pkg__"], 136 | ) 137 | -------------------------------------------------------------------------------- /unit-test/depends.mk: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | ## Modified this file to specify your library path. 3 | ## 4 | ## Depending libs: 5 | ## gtest-1.7.0 6 | ## 7 | ############################################################### 8 | 9 | ############################################################### 10 | ## Google Test directory. 11 | ## 12 | ## Check file exist: 13 | ## $(GTEST_DIR)/src/gtest-all.cc 14 | ## 15 | #GTEST_DIR=/home/users/qinzuoyan01/libs/gtest-1.7.0 16 | GTEST_DIR=../googletest/googletest 17 | ############################################################### 18 | 19 | -------------------------------------------------------------------------------- /unit-test/run_bazel_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function build() 4 | { 5 | name=$(echo $1 | awk -F '.' '{print $2}' | awk -F '/' '{print $2}') 6 | bazel build :$name 7 | if [ $? -ne 0 ]; then 8 | echo "BUILD FAILED!!! for $name" 9 | exit 1 10 | fi 11 | } 12 | 13 | function run() 14 | { 15 | name=$(echo $1 | awk -F '.' '{print $2}' | awk -F '/' '{print $2}') 16 | echo "===========" $name "===========" 17 | bazel run :$name 18 | ../bazel-bin/unit-test/$name 19 | if [ $? -ne 0 ]; then 20 | echo "TEST FAILED!!!" 21 | exit 1 22 | fi 23 | } 24 | 25 | num=0 26 | for test_case in `find . -name 'test_*.cc' -a` # -perm -100` 27 | do 28 | build $test_case 29 | num=$((num+1)) 30 | done 31 | 32 | num=0 33 | for test_case in `find . -name 'test_*.cc' -a` # -perm -100` 34 | do 35 | run $test_case 36 | num=$((num+1)) 37 | done 38 | 39 | echo 40 | echo "CASE NUM: $num" 41 | echo "ALL CASE PASSED!!!" 42 | -------------------------------------------------------------------------------- /unit-test/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function run() 4 | { 5 | echo "===========" $1 "===========" 6 | ./$1 7 | if [ $? -ne 0 ]; then 8 | echo "TEST FAILED!!!" 9 | exit 1 10 | fi 11 | } 12 | 13 | num=0 14 | for test_case in `find . -name 'test_*' -a -perm -100` 15 | do 16 | run $test_case 17 | num=$((num+1)) 18 | done 19 | 20 | echo 21 | echo "CASE NUM: $num" 22 | echo "ALL CASE PASSED!!!" 23 | 24 | -------------------------------------------------------------------------------- /unit-test/test_atomic.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | using namespace sofa::pbrpc; 9 | 10 | class AtomicTest: public ::testing::Test {}; 11 | 12 | TEST_F(AtomicTest, test) 13 | { 14 | const int g = 1024 * 1024 * 1024; 15 | int a = 10; 16 | ASSERT_EQ(10, atomic_add_ret_old(&a, 5)); 17 | ASSERT_EQ(15, a); 18 | ASSERT_EQ(15, atomic_add_ret_old(&a, -10)); 19 | ASSERT_EQ(5, a); 20 | ASSERT_EQ(5, atomic_add_ret_old(&a, -5)); 21 | ASSERT_EQ(0, a); 22 | ASSERT_EQ(0, atomic_add_ret_old(&a, -5)); 23 | ASSERT_EQ(-5, a); 24 | ASSERT_EQ(-5, atomic_add_ret_old(&a, 5)); 25 | ASSERT_EQ(0, a); 26 | ASSERT_EQ(0, atomic_add_ret_old(&a, g)); 27 | ASSERT_EQ(g, a); 28 | ASSERT_EQ(g, atomic_add_ret_old(&a, -g * 2)); 29 | ASSERT_EQ(-g, a); 30 | 31 | ASSERT_EQ(-g, atomic_swap(&a, 0)); 32 | ASSERT_EQ(0, a); 33 | 34 | ASSERT_EQ(0, atomic_comp_swap(&a, 1, 1)); 35 | ASSERT_EQ(0, a); 36 | 37 | ASSERT_EQ(0, atomic_comp_swap(&a, 1, 0)); 38 | ASSERT_EQ(1, a); 39 | } 40 | 41 | int main(int argc, char **argv) 42 | { 43 | ::testing::InitGoogleTest(&argc, argv); 44 | return RUN_ALL_TESTS(); 45 | } 46 | 47 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 48 | -------------------------------------------------------------------------------- /unit-test/test_common.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | using namespace sofa; 9 | 10 | class CommonTest : public ::testing::Test 11 | { 12 | protected: 13 | CommonTest(){}; 14 | virtual ~CommonTest(){}; 15 | virtual void SetUp() { 16 | //Called befor every TEST_F(CommonTest, *) 17 | }; 18 | virtual void TearDown() { 19 | //Called after every TEST_F(CommonTest, *) 20 | }; 21 | }; 22 | 23 | TEST_F(CommonTest, test_log) 24 | { 25 | sofa::pbrpc::internal::set_log_level(sofa::pbrpc::LOG_LEVEL_NOTICE); 26 | int flag_notice = 0; 27 | SLOG(NOTICE, "notice message: %d: %s", ++flag_notice, "should be logged"); 28 | ASSERT_EQ(1, flag_notice); 29 | int flag_trace = 0; 30 | SLOG(TRACE, "trace message: %d: %s", ++flag_trace, "should not be logged"); 31 | ASSERT_EQ(0, flag_trace); 32 | } 33 | 34 | TEST_F(CommonTest, test_check) 35 | { 36 | int value = 1; 37 | SCHECK_EQ(1, value); 38 | SCHECK_LE(1, value); 39 | SCHECK_LE(0, value); 40 | SCHECK_LT(0, value); 41 | SCHECK_GE(1, value); 42 | SCHECK_GE(2, value); 43 | SCHECK_GT(2, value); 44 | } 45 | 46 | static std::string s_test_log_buf; 47 | void test_log_handler( 48 | sofa::pbrpc::LogLevel level, const char* filename, int, 49 | const char *fmt, va_list ap) 50 | { 51 | char buf[1024]; 52 | vsnprintf(buf, 1024, fmt, ap); 53 | char result[1500]; 54 | snprintf(result, 1024, "level=%d filename=%s %s", level, filename, buf); 55 | s_test_log_buf.assign(result); 56 | } 57 | 58 | TEST_F(CommonTest, test_set_log_handler) 59 | { 60 | sofa::pbrpc::LogHandler *old = sofa::pbrpc::set_log_handler(test_log_handler); 61 | ASSERT_NE(old, (void*)NULL); 62 | 63 | SLOG(ERROR, "found error %s", "boom!"); 64 | #ifdef BAZEL_BUILD 65 | ASSERT_STREQ(s_test_log_buf.c_str(), "level=1 filename=unit-test/test_common.cc found error boom!"); 66 | #else 67 | ASSERT_STREQ(s_test_log_buf.c_str(), "level=1 filename=test_common.cc found error boom!"); 68 | #endif 69 | } 70 | 71 | int main(int argc, char **argv) 72 | { 73 | ::testing::InitGoogleTest(&argc, argv); 74 | return RUN_ALL_TESTS(); 75 | } 76 | 77 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 78 | -------------------------------------------------------------------------------- /unit-test/test_data.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package sofa.pbrpc.test; 4 | 5 | message TestData { 6 | required int32 v1 = 1; 7 | optional int64 v2 = 2; 8 | optional bool v3 = 3; 9 | optional bytes v4 = 4; 10 | optional string v5 = 5; 11 | } 12 | -------------------------------------------------------------------------------- /unit-test/test_epoll_support.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | class EpollSupportTest: public ::testing::Test {}; 9 | 10 | #ifndef __APPLE__ 11 | 12 | TEST_F(EpollSupportTest, test) 13 | { 14 | std::string output; 15 | #if defined(BOOST_ASIO_HAS_IOCP) 16 | output = "iocp" ; 17 | #elif defined(BOOST_ASIO_HAS_EPOLL) 18 | output = "epoll" ; 19 | #elif defined(BOOST_ASIO_HAS_KQUEUE) 20 | output = "kqueue" ; 21 | #elif defined(BOOST_ASIO_HAS_DEV_POLL) 22 | output = "/dev/poll" ; 23 | #else 24 | output = "select" ; 25 | #endif 26 | ASSERT_EQ("epoll", output); 27 | } 28 | 29 | #endif 30 | 31 | int main(int argc, char **argv) 32 | { 33 | ::testing::InitGoogleTest(&argc, argv); 34 | return RUN_ALL_TESTS(); 35 | } 36 | 37 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 38 | -------------------------------------------------------------------------------- /unit-test/test_io_service_pool.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | using namespace ::sofa::pbrpc; 9 | 10 | class IOServicePoolTest: public ::testing::Test 11 | { 12 | protected: 13 | IOServicePoolTest() { } 14 | 15 | virtual ~IOServicePoolTest() { } 16 | 17 | virtual void SetUp() { } 18 | 19 | virtual void TearDown() { } 20 | }; 21 | 22 | TEST(IOServicePool, Run) 23 | { 24 | IOServicePool* pool = new IOServicePool(2, 8); 25 | bool ret = pool->Run(); 26 | delete pool; 27 | ASSERT_TRUE(ret == true); 28 | } 29 | 30 | TEST(IOServicePool, GetIOService) 31 | { 32 | IOServicePool* pool = new IOServicePool(2, 8); 33 | IOService& io_service1 = pool->GetIOService(); 34 | IOService& io_service2 = pool->GetIOService(); 35 | ASSERT_TRUE(&io_service1 != &io_service2); 36 | 37 | IOService& io_service3 = pool->GetIOService(); 38 | ASSERT_TRUE(&io_service3 == &io_service1); 39 | delete pool; 40 | } 41 | 42 | TEST(IOServicePool, Stop) 43 | { 44 | IOServicePool* pool = new IOServicePool(2, 8); 45 | pool->Stop(); 46 | delete pool; 47 | } 48 | 49 | int main(int argc, char **argv) 50 | { 51 | ::testing::InitGoogleTest(&argc, argv); 52 | return RUN_ALL_TESTS(); 53 | } 54 | -------------------------------------------------------------------------------- /unit-test/test_thread_group.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class ThreadGroupTest: public ::testing::Test 10 | { 11 | protected: 12 | ThreadGroupTest() {} 13 | virtual ~ThreadGroupTest() {} 14 | virtual void SetUp() { 15 | // Called before every TEST_F(ThreadGroupTest, *) 16 | } 17 | virtual void TearDown() { 18 | // Called after every TEST_F(ThreadGroupTest, *) 19 | } 20 | }; 21 | 22 | static void test_1_function(bool* called) 23 | { 24 | *called = true; 25 | } 26 | 27 | TEST_F(ThreadGroupTest, test_1) 28 | { 29 | sofa::pbrpc::ThreadGroup* thread_group = new sofa::pbrpc::ThreadGroup(4); 30 | 31 | bool dispatch_called = false; 32 | thread_group->dispatch(sofa::pbrpc::NewClosure(&test_1_function, &dispatch_called)); 33 | 34 | bool post_called = false; 35 | thread_group->post(sofa::pbrpc::NewClosure(&test_1_function, &post_called)); 36 | 37 | delete thread_group; 38 | 39 | ASSERT_TRUE(dispatch_called); 40 | ASSERT_TRUE(post_called); 41 | } 42 | 43 | int main(int argc, char **argv) 44 | { 45 | ::testing::InitGoogleTest(&argc, argv); 46 | return RUN_ALL_TESTS(); 47 | } 48 | 49 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 50 | -------------------------------------------------------------------------------- /unit-test/test_tran_buf_pool.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #define SOFA_PBRPC_TRAN_BUF_BLOCK_SIZE (64u) 6 | 7 | #include 8 | #include 9 | 10 | using namespace sofa::pbrpc; 11 | 12 | class TranBufPoolTest : public ::testing::Test {}; 13 | 14 | TEST_F(TranBufPoolTest, malloc_free_test) 15 | { 16 | void* data = TranBufPool::malloc(4); 17 | ASSERT_TRUE(NULL != data); 18 | ASSERT_EQ(1024, TranBufPool::block_size(data)); 19 | ASSERT_EQ(1024 - sizeof(int) * 2, TranBufPool::capacity(data)); 20 | TranBufPool::free(data); 21 | } 22 | 23 | TEST_F(TranBufPoolTest, add_ref_test) 24 | { 25 | void* data = TranBufPool::malloc(4); 26 | ASSERT_TRUE(NULL != data); 27 | TranBufPool::add_ref(data); 28 | TranBufPool::free(data); 29 | TranBufPool::free(data); 30 | } 31 | 32 | int main(int argc, char **argv) 33 | { 34 | ::testing::InitGoogleTest(&argc, argv); 35 | return RUN_ALL_TESTS(); 36 | } 37 | 38 | /* vim: set ts=4 sw=4 sts=4 tw=100 */ 39 | -------------------------------------------------------------------------------- /unit-test/test_web_service.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Baidu.com, Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace ::sofa::pbrpc; 10 | 11 | class WebServiceTest: public ::testing::Test 12 | { 13 | protected: 14 | WebServiceTest() { } 15 | 16 | virtual ~WebServiceTest() { } 17 | 18 | virtual void SetUp() { 19 | _service_pool.reset(new ServicePool(NULL)); 20 | } 21 | 22 | virtual void TearDown() { 23 | _service_pool.reset(); 24 | } 25 | 26 | ServicePoolPtr _service_pool; 27 | }; 28 | 29 | TEST_F(WebServiceTest, RegisterServlet) 30 | { 31 | WebServicePtr web_service(new WebService(_service_pool)); 32 | Servlet s = (Servlet) 0x01; 33 | std::string path = "/a/b/c"; 34 | bool ret = web_service->RegisterServlet(path, s); 35 | ASSERT_TRUE(ret); 36 | ret = web_service->RegisterServlet(path, s); 37 | ASSERT_FALSE(ret); 38 | ret = web_service->UnregisterServlet(path); 39 | ASSERT_TRUE(ret); 40 | } 41 | 42 | TEST_F(WebServiceTest, FindServlet) 43 | { 44 | WebServicePtr web_service(new WebService(_service_pool)); 45 | Servlet null_servlet = web_service->FindServlet("null"); 46 | ASSERT_TRUE(NULL == null_servlet); 47 | 48 | Servlet s1 = (Servlet) 0x01; 49 | Servlet s2 = (Servlet) 0x02; 50 | Servlet s3 = (Servlet) 0x03; 51 | 52 | std::string p1 = "/"; 53 | std::string p2 = "/a"; 54 | std::string p3 = "/a/b"; 55 | 56 | web_service->RegisterServlet(p1, s1); 57 | web_service->RegisterServlet(p2, s2); 58 | web_service->RegisterServlet(p3, s3); 59 | 60 | Servlet find = web_service->FindServlet(p1); 61 | ASSERT_EQ(find, s1); 62 | 63 | std::string path = "/null"; 64 | find = web_service->FindServlet(path); 65 | ASSERT_TRUE(NULL == null_servlet); 66 | 67 | path = "/a"; 68 | find = web_service->FindServlet(path); 69 | ASSERT_EQ(find, s2); 70 | 71 | path = "/a/b/something"; 72 | find = web_service->FindServlet(path); 73 | ASSERT_EQ(find, s3); 74 | 75 | web_service->UnregisterServlet(p1); 76 | web_service->UnregisterServlet(p2); 77 | web_service->UnregisterServlet(p3); 78 | } 79 | 80 | int main(int argc, char **argv) 81 | { 82 | ::testing::InitGoogleTest(&argc, argv); 83 | return RUN_ALL_TESTS(); 84 | } 85 | --------------------------------------------------------------------------------