├── third_party
├── BUILD
├── lz4.BUILD
└── snappy.BUILD
├── src
├── include
│ └── srpc
│ │ ├── rpc_basic.h
│ │ ├── rpc_buffer.h
│ │ ├── rpc_client.h
│ │ ├── rpc_define.h
│ │ ├── rpc_global.h
│ │ ├── rpc_server.h
│ │ ├── rpc_task.inl
│ │ ├── rpc_types.h
│ │ ├── rpc_var.h
│ │ ├── parser.h
│ │ ├── printer.h
│ │ ├── rpc_context.h
│ │ ├── rpc_context.inl
│ │ ├── rpc_options.h
│ │ ├── rpc_service.h
│ │ ├── descriptor.h
│ │ ├── generator.h
│ │ ├── rpc_filter.h
│ │ ├── rpc_message.h
│ │ ├── rpc_module.h
│ │ ├── ckms_quantiles.h
│ │ ├── rpc_compress.h
│ │ ├── rpc_thrift_idl.h
│ │ ├── rpc_compress_lz4.h
│ │ ├── rpc_message_brpc.h
│ │ ├── rpc_message_srpc.h
│ │ ├── rpc_message_trpc.h
│ │ ├── rpc_thrift_buffer.h
│ │ ├── rpc_thrift_enum.h
│ │ ├── rpc_thrift_idl.inl
│ │ ├── rpc_trace_filter.h
│ │ ├── rpc_trace_module.h
│ │ ├── rpc_zero_copy_stream.h
│ │ ├── rpc_compress_gzip.h
│ │ ├── rpc_message_thrift.h
│ │ ├── rpc_metrics_filter.h
│ │ ├── rpc_metrics_module.h
│ │ ├── time_window_quantiles.h
│ │ └── rpc_compress_snappy.h
├── thrift
│ ├── CMakeLists.txt
│ ├── rpc_thrift_enum.h
│ ├── rpc_thrift_idl.h
│ └── rpc_thrift_buffer.h
├── var
│ ├── CMakeLists.txt
│ └── time_window_quantiles.h
├── http
│ ├── CMakeLists.txt
│ ├── http_server.h
│ ├── http_module.h
│ ├── http_client.h
│ └── http_server.cc
├── generator
│ ├── CMakeLists.txt
│ ├── generator.h
│ └── parser.h
├── message
│ ├── CMakeLists.txt
│ ├── rpc_meta.proto
│ └── rpc_meta_trpc.proto
├── module
│ ├── CMakeLists.txt
│ ├── proto
│ │ ├── opentelemetry_resource.proto
│ │ ├── opentelemetry_metrics_service.proto
│ │ └── opentelemetry_common.proto
│ ├── rpc_metrics_module.cc
│ └── rpc_metrics_module.h
├── compress
│ ├── CMakeLists.txt
│ ├── rpc_compress_snappy.h
│ ├── rpc_compress.cc
│ └── rpc_compress_snappy.cc
├── rpc_global.h
├── rpc_define.h
├── rpc_basic.cc
├── rpc_options.h
├── rpc_service.h
├── rpc_zero_copy_stream.h
└── rpc_global.cc
├── tools
├── templates
│ ├── file
│ │ ├── 404.html
│ │ ├── index.html
│ │ ├── server.conf
│ │ ├── 50x.html
│ │ ├── server_main.cc
│ │ ├── file_service.h
│ │ └── file_service.cc
│ ├── rpc
│ │ ├── server.conf
│ │ ├── rpc.thrift
│ │ ├── client.conf
│ │ ├── rpc.proto
│ │ ├── server_thrift.cc
│ │ ├── server_protobuf.cc
│ │ ├── client_protobuf.cc
│ │ ├── client_thrift.cc
│ │ └── CMakeLists.txt
│ ├── basic
│ │ ├── server.conf
│ │ ├── client.conf
│ │ ├── server_main.cc
│ │ ├── client_main.cc
│ │ └── compute_server_main.cc
│ ├── proxy
│ │ ├── proxy.conf
│ │ ├── client_rpc.conf
│ │ ├── proxy_main_proto.cc
│ │ └── proxy_main.cc
│ ├── common
│ │ ├── GNUmakefile
│ │ ├── util.h
│ │ ├── CMakeLists.txt
│ │ └── config.json
│ └── config
│ │ ├── config_simple.h
│ │ └── config_full.h
├── GNUmakefile
├── CMakeLists.txt
└── srpc_ctl.cc
├── docs
├── images
│ ├── benchmark1.png
│ ├── benchmark2.png
│ ├── benchmark3.png
│ ├── benchmark4.png
│ ├── benchmark5.png
│ └── benchmark6.png
├── docs-01-idl.md
├── en
│ ├── docs-01-idl.md
│ ├── docs-02-service.md
│ ├── docs-04-client.md
│ ├── docs-03-server.md
│ └── docs-05-context.md
├── docs-02-service.md
├── docs-04-client.md
├── docs-03-server.md
├── docs-05-context.md
└── installation.md
├── .bazelignore
├── .editorconfig
├── benchmark
├── benchmark_thrift.thrift
├── benchmark_pb.proto
├── test.py
├── GNUmakefile
└── thrift_server.cc
├── test
├── test_thrift.thrift
├── test_pb.proto
├── GNUmakefile
└── var_unittest.cc
├── tutorial
├── echo_thrift.thrift
├── helloworld.proto
├── echo_pb.proto
├── GNUmakefile
├── tutorial-07-thrift_thrift_server.cc
├── tutorial-02-srpc_pb_client.cc
├── tutorial-01-srpc_pb_server.cc
├── tutorial-03-srpc_thrift_server.cc
├── tutorial-14-trpc_http_client.cc
├── tutorial-12-trpc_pb_client.cc
├── tutorial-18-http_client.cc
├── tutorial-05-brpc_pb_server.cc
├── tutorial-06-brpc_pb_client.cc
├── tutorial-17-http_server.cc
├── tutorial-09-client_task.cc
├── tutorial-04-srpc_thrift_client.cc
├── tutorial-11-trpc_pb_server.cc
├── tutorial-13-trpc_http_server.cc
├── tutorial-15-srpc_pb_proxy.cc
├── tutorial-10-server_async.cc
├── tutorial-08-thrift_thrift_client.cc
└── tutorial-16-server_with_metrics.cc
├── .gitmodules
├── srpc-config.cmake.in
├── .gitignore
├── WORKSPACE
├── CMakeLists_Headers.txt
├── GNUmakefile
├── srpc.bzl
├── .github
└── workflows
│ └── ci.yml
└── CODE_OF_CONDUCT.md
/third_party/BUILD:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/include/srpc/rpc_basic.h:
--------------------------------------------------------------------------------
1 | ../../rpc_basic.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_buffer.h:
--------------------------------------------------------------------------------
1 | ../../rpc_buffer.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_client.h:
--------------------------------------------------------------------------------
1 | ../../rpc_client.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_define.h:
--------------------------------------------------------------------------------
1 | ../../rpc_define.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_global.h:
--------------------------------------------------------------------------------
1 | ../../rpc_global.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_server.h:
--------------------------------------------------------------------------------
1 | ../../rpc_server.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_task.inl:
--------------------------------------------------------------------------------
1 | ../../rpc_task.inl
--------------------------------------------------------------------------------
/src/include/srpc/rpc_types.h:
--------------------------------------------------------------------------------
1 | ../../rpc_types.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_var.h:
--------------------------------------------------------------------------------
1 | ../../var/rpc_var.h
--------------------------------------------------------------------------------
/src/include/srpc/parser.h:
--------------------------------------------------------------------------------
1 | ../../generator/parser.h
--------------------------------------------------------------------------------
/src/include/srpc/printer.h:
--------------------------------------------------------------------------------
1 | ../../generator/printer.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_context.h:
--------------------------------------------------------------------------------
1 | ../../rpc_context.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_context.inl:
--------------------------------------------------------------------------------
1 | ../../rpc_context.inl
--------------------------------------------------------------------------------
/src/include/srpc/rpc_options.h:
--------------------------------------------------------------------------------
1 | ../../rpc_options.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_service.h:
--------------------------------------------------------------------------------
1 | ../../rpc_service.h
--------------------------------------------------------------------------------
/src/include/srpc/descriptor.h:
--------------------------------------------------------------------------------
1 | ../../generator/descriptor.h
--------------------------------------------------------------------------------
/src/include/srpc/generator.h:
--------------------------------------------------------------------------------
1 | ../../generator/generator.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_filter.h:
--------------------------------------------------------------------------------
1 | ../../module/rpc_filter.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_message.h:
--------------------------------------------------------------------------------
1 | ../../message/rpc_message.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_module.h:
--------------------------------------------------------------------------------
1 | ../../module/rpc_module.h
--------------------------------------------------------------------------------
/src/include/srpc/ckms_quantiles.h:
--------------------------------------------------------------------------------
1 | ../../var/ckms_quantiles.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_compress.h:
--------------------------------------------------------------------------------
1 | ../../compress/rpc_compress.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_thrift_idl.h:
--------------------------------------------------------------------------------
1 | ../../thrift/rpc_thrift_idl.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_compress_lz4.h:
--------------------------------------------------------------------------------
1 | ../../compress/rpc_compress_lz4.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_message_brpc.h:
--------------------------------------------------------------------------------
1 | ../../message/rpc_message_brpc.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_message_srpc.h:
--------------------------------------------------------------------------------
1 | ../../message/rpc_message_srpc.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_message_trpc.h:
--------------------------------------------------------------------------------
1 | ../../message/rpc_message_trpc.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_thrift_buffer.h:
--------------------------------------------------------------------------------
1 | ../../thrift/rpc_thrift_buffer.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_thrift_enum.h:
--------------------------------------------------------------------------------
1 | ../../thrift/rpc_thrift_enum.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_thrift_idl.inl:
--------------------------------------------------------------------------------
1 | ../../thrift/rpc_thrift_idl.inl
--------------------------------------------------------------------------------
/src/include/srpc/rpc_trace_filter.h:
--------------------------------------------------------------------------------
1 | ../../module/rpc_trace_filter.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_trace_module.h:
--------------------------------------------------------------------------------
1 | ../../module/rpc_trace_module.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_zero_copy_stream.h:
--------------------------------------------------------------------------------
1 | ../../rpc_zero_copy_stream.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_compress_gzip.h:
--------------------------------------------------------------------------------
1 | ../../compress/rpc_compress_gzip.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_message_thrift.h:
--------------------------------------------------------------------------------
1 | ../../message/rpc_message_thrift.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_metrics_filter.h:
--------------------------------------------------------------------------------
1 | ../../module/rpc_metrics_filter.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_metrics_module.h:
--------------------------------------------------------------------------------
1 | ../../module/rpc_metrics_module.h
--------------------------------------------------------------------------------
/src/include/srpc/time_window_quantiles.h:
--------------------------------------------------------------------------------
1 | ../../var/time_window_quantiles.h
--------------------------------------------------------------------------------
/src/include/srpc/rpc_compress_snappy.h:
--------------------------------------------------------------------------------
1 | ../../compress/rpc_compress_snappy.h
--------------------------------------------------------------------------------
/tools/templates/file/404.html:
--------------------------------------------------------------------------------
1 | This is not the web page you are looking for.
2 |
--------------------------------------------------------------------------------
/tools/templates/file/index.html:
--------------------------------------------------------------------------------
1 | Hello from workflow and srpc file server!
2 |
--------------------------------------------------------------------------------
/docs/images/benchmark1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sogou/srpc/HEAD/docs/images/benchmark1.png
--------------------------------------------------------------------------------
/docs/images/benchmark2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sogou/srpc/HEAD/docs/images/benchmark2.png
--------------------------------------------------------------------------------
/docs/images/benchmark3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sogou/srpc/HEAD/docs/images/benchmark3.png
--------------------------------------------------------------------------------
/docs/images/benchmark4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sogou/srpc/HEAD/docs/images/benchmark4.png
--------------------------------------------------------------------------------
/docs/images/benchmark5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sogou/srpc/HEAD/docs/images/benchmark5.png
--------------------------------------------------------------------------------
/docs/images/benchmark6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sogou/srpc/HEAD/docs/images/benchmark6.png
--------------------------------------------------------------------------------
/tools/templates/rpc/server.conf:
--------------------------------------------------------------------------------
1 | {
2 | "server":
3 | {
4 | "port": 1412
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/tools/templates/basic/server.conf:
--------------------------------------------------------------------------------
1 | {
2 | "server":
3 | {
4 | "port": %u
5 | }
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/.bazelignore:
--------------------------------------------------------------------------------
1 | ./third_party/snappy/third_party/benchmark
2 | ./third_party/snappy/third_party/googletest
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most EditorConfig file
2 | root = true
3 |
4 | # all files
5 | [*]
6 | indent_style = tab
7 | indent_size = 4
8 |
--------------------------------------------------------------------------------
/benchmark/benchmark_thrift.thrift:
--------------------------------------------------------------------------------
1 | service BenchmarkThrift
2 | {
3 | void echo_thrift(1:string msg);
4 | void slow_thrift(1:string msg);
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/tools/templates/basic/client.conf:
--------------------------------------------------------------------------------
1 | {
2 | "client":
3 | {
4 | "remote_host": "127.0.0.1",
5 | "remote_port": %u,%s
6 | "retry_max": 2%s
7 | }
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/test/test_thrift.thrift:
--------------------------------------------------------------------------------
1 | namespace cpp unit;
2 |
3 | service TestThrift {
4 | i32 add(1:i32 a, 2:i32 b);
5 | string substr(1:string str, 2:i32 idx, 3:i32 length);
6 | };
7 |
8 |
--------------------------------------------------------------------------------
/src/thrift/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(thrift)
3 |
4 | set(SRC
5 | rpc_thrift_buffer.cc
6 | rpc_thrift_idl.cc
7 | )
8 |
9 | add_library(${PROJECT_NAME} OBJECT ${SRC})
10 |
11 |
--------------------------------------------------------------------------------
/tools/templates/rpc/rpc.thrift:
--------------------------------------------------------------------------------
1 | struct EchoResult {
2 | 1:required string message;
3 | 2:optional i32 state;
4 | 3:optional i32 error;
5 | }
6 |
7 | service %s {
8 | EchoResult Echo(1:string message);
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/tools/templates/proxy/proxy.conf:
--------------------------------------------------------------------------------
1 | {
2 | "server":
3 | {
4 | "port": %s
5 | },
6 |
7 | "client":
8 | {
9 | "remote_host": "127.0.0.1",
10 | "remote_port": %s,
11 | "retry_max": 2
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/tools/templates/rpc/client.conf:
--------------------------------------------------------------------------------
1 | {
2 | "client":
3 | {
4 | "remote_host": "127.0.0.1",
5 | "remote_port": 1412,
6 | "is_ssl" : false,
7 | "retry_max": 1,
8 | "callee" : "rpc_client"
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/src/var/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(var)
3 |
4 | include_directories(${CMAKE_CURRENT_BINARY_DIR})
5 |
6 | set(SRC
7 | rpc_var.cc
8 | )
9 |
10 | add_library(${PROJECT_NAME} OBJECT ${SRC})
11 |
12 |
--------------------------------------------------------------------------------
/tools/templates/proxy/client_rpc.conf:
--------------------------------------------------------------------------------
1 | {
2 | "client":
3 | {
4 | "remote_host": "127.0.0.1",
5 | "remote_port": 1411,
6 | "is_ssl" : false,
7 | "retry_max": 1,
8 | "callee" : "rpc_client"
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/tutorial/echo_thrift.thrift:
--------------------------------------------------------------------------------
1 | struct EchoResult {
2 | 1:required string message;
3 | 2:optional i32 state;
4 | 3:optional i32 error;
5 | }
6 |
7 | service Example {
8 | EchoResult Echo(1:string message, 2:string name);
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/benchmark/benchmark_pb.proto:
--------------------------------------------------------------------------------
1 | syntax="proto3";
2 |
3 | message EmptyPBMsg { }
4 |
5 | message FixLengthPBMsg { bytes msg = 1; }
6 |
7 | service BenchmarkPB
8 | {
9 | rpc echo_pb(FixLengthPBMsg) returns (EmptyPBMsg);
10 | rpc slow_pb(FixLengthPBMsg) returns (EmptyPBMsg);
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/tools/templates/rpc/rpc.proto:
--------------------------------------------------------------------------------
1 | syntax="proto2";
2 |
3 | message EchoRequest {
4 | required string message = 1;
5 | };
6 |
7 | message EchoResponse {
8 | required string message = 1;
9 | optional int32 state = 2;
10 | optional int32 error = 3;
11 | };
12 |
13 | service %s {
14 | rpc Echo(EchoRequest) returns (EchoResponse);
15 | };
16 |
17 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "workflow"]
2 | path = workflow
3 | url = https://github.com/sogou/workflow.git
4 | [submodule "third_party/snappy"]
5 | path = third_party/snappy
6 | url = https://github.com/google/snappy
7 | branch = 1.1.9
8 | [submodule "third_party/lz4"]
9 | path = third_party/lz4
10 | url = https://github.com/lz4/lz4
11 | branch = v1.9.3
12 |
--------------------------------------------------------------------------------
/tools/templates/file/server.conf:
--------------------------------------------------------------------------------
1 | {
2 | "server":
3 | {
4 | "port": 8080,
5 | "root": "./html/",
6 | "error_page" : [
7 | {
8 | "error" : [ 404 ],
9 | "page" : "404.html"
10 | },
11 | {
12 | "error" : [ 500, 502, 503, 504],
13 | "page" : "50x.html"
14 | }
15 | ]
16 | }
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/tutorial/helloworld.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package trpc.test.helloworld;
4 |
5 | service Greeter {
6 | rpc SayHello (HelloRequest) returns (HelloReply) {}
7 | rpc SayHi (HelloRequest) returns (HelloReply) {}
8 | }
9 |
10 | message HelloRequest {
11 | string msg = 1;
12 | }
13 |
14 | message HelloReply {
15 | string msg = 1;
16 | }
17 |
--------------------------------------------------------------------------------
/tutorial/echo_pb.proto:
--------------------------------------------------------------------------------
1 | syntax="proto2";
2 |
3 | message EchoRequest {
4 | required string message = 1;
5 | required string name = 2;
6 | };
7 |
8 | message EchoResponse {
9 | required string message = 1;
10 | optional int32 state = 2;
11 | optional int32 error = 3;
12 | };
13 |
14 | service Example {
15 | rpc Echo(EchoRequest) returns (EchoResponse);
16 | };
17 |
18 |
--------------------------------------------------------------------------------
/third_party/lz4.BUILD:
--------------------------------------------------------------------------------
1 | cc_library(
2 | name = "lz4",
3 | srcs = [
4 | 'lib/lz4.c',
5 | 'lib/lz4hc.c',
6 | 'lib/lz4frame.c',
7 | 'lib/xxhash.c',
8 | ],
9 | hdrs = [
10 | 'lib/lz4.h',
11 | 'lib/lz4.c',
12 | 'lib/lz4hc.h',
13 | 'lib/lz4frame.h',
14 | 'lib/xxhash.h',
15 | ],
16 | includes = ['lib'],
17 | visibility = ["//visibility:public"],
18 | )
19 |
--------------------------------------------------------------------------------
/tools/templates/common/GNUmakefile:
--------------------------------------------------------------------------------
1 | ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
2 | BUILD_DIR := build.cmake
3 |
4 | .PHONY: all clean
5 |
6 | all: base
7 | make -C $(BUILD_DIR) -f Makefile
8 |
9 | base:
10 | mkdir -p $(BUILD_DIR)
11 | cd $(BUILD_DIR) && cmake $(ROOT_DIR)
12 |
13 | clean:
14 | ifeq ($(BUILD_DIR), $(wildcard $(BUILD_DIR)))
15 | make -C $(BUILD_DIR) clean
16 | rm -rf $(BUILD_DIR)
17 | endif
18 |
19 |
--------------------------------------------------------------------------------
/srpc-config.cmake.in:
--------------------------------------------------------------------------------
1 | @PACKAGE_INIT@
2 |
3 | set(SRPC_VERSION "@srpc_VERSION@")
4 | set_and_check(SRPC_INCLUDE_DIR "@PACKAGE_CONFIG_INC_DIR@")
5 | set_and_check(SRPC_LIB_DIR "@PACKAGE_CONFIG_LIB_DIR@")
6 | set_and_check(SRPC_BIN_DIR "@PACKAGE_CONFIG_BIN_DIR@")
7 |
8 | if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/srpc-targets.cmake")
9 | include ("${CMAKE_CURRENT_LIST_DIR}/srpc-targets.cmake")
10 | endif ()
11 |
12 | check_required_components(srpc)
13 |
14 |
--------------------------------------------------------------------------------
/tools/GNUmakefile:
--------------------------------------------------------------------------------
1 | ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
2 | BUILD_DIR := build.cmake
3 |
4 | .PHONY: all clean
5 |
6 | all: base
7 | make -C $(BUILD_DIR) -f Makefile
8 |
9 | base:
10 | mkdir -p $(BUILD_DIR)
11 | cd $(BUILD_DIR) && cmake -D CMAKE_BUILD_TYPE=Debug $(ROOT_DIR)
12 |
13 | clean:
14 | ifeq ($(BUILD_DIR), $(wildcard $(BUILD_DIR)))
15 | make -C $(BUILD_DIR) clean
16 | rm -rf $(BUILD_DIR)
17 | endif
18 |
19 |
--------------------------------------------------------------------------------
/src/http/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(http)
3 |
4 | include_directories(${CMAKE_CURRENT_BINARY_DIR})
5 |
6 | set(SRC
7 | http_module.cc
8 | http_task.cc
9 | http_client.cc
10 | http_server.cc
11 | )
12 |
13 | add_library(${PROJECT_NAME} OBJECT ${SRC})
14 | if (WIN32)
15 | target_compile_definitions(
16 | ${PROJECT_NAME} PRIVATE
17 | strdup=_strdup
18 | strcasecmp=_stricmp
19 | strncasecmp=_strnicmp
20 | )
21 | endif ()
22 |
23 |
--------------------------------------------------------------------------------
/src/generator/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(srpc_generator)
3 |
4 | set(SRC
5 | compiler.cc
6 | generator.cc
7 | parser.cc
8 | )
9 |
10 | add_executable(${PROJECT_NAME} ${SRC})
11 | if (WIN32)
12 | target_compile_definitions(
13 | ${PROJECT_NAME} PRIVATE
14 | getcwd=_getcwd
15 | strdup=_strdup
16 | strcasecmp=_stricmp
17 | strncasecmp=_strnicmp
18 | )
19 | endif ()
20 |
21 | install(
22 | TARGETS ${PROJECT_NAME}
23 | RUNTIME
24 | DESTINATION ${CMAKE_INSTALL_BINDIR}
25 | COMPONENT devel
26 | )
27 |
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.a
2 | *.bak
3 | *.gz
4 | *.zip
5 | *.tar
6 | *.la
7 | *.lo
8 | *.o
9 | *.rpm
10 | *.so
11 | *.so.*
12 | *.cmake
13 | *.vcxproj
14 | *.filters
15 | *.sln
16 | *.pb.h
17 | *.pb.cc
18 | *.log
19 | *.srpc.h
20 | *.thrift.h
21 | *.pb_skeleton.h
22 | *.pb_skeleton.cc
23 | *.thrift_skeleton.h
24 | *.thrift_skeleton.cc
25 |
26 | _bin/
27 | _include/
28 | _lib/
29 | .deps/
30 | build/
31 | build_pkg/
32 | CMakeFiles/
33 | Debug/
34 | Release/
35 |
36 | missing
37 | SRCINFO
38 | SRCNUMVER
39 | SRCVERSION
40 | CMakeCache.txt
41 | Makefile
42 |
43 | bazel-*
44 |
--------------------------------------------------------------------------------
/test/test_pb.proto:
--------------------------------------------------------------------------------
1 | syntax="proto2";
2 | package unit;
3 |
4 | message AddRequest {
5 | required int32 a = 1;
6 | required int32 b = 2;
7 | };
8 |
9 | message AddResponse {
10 | required int32 c = 1;
11 | };
12 |
13 | message SubstrRequest {
14 | required string str = 1;
15 | required int32 idx = 2;
16 | optional int32 length = 3;
17 | };
18 |
19 | message SubstrResponse {
20 | required string str = 1;
21 | };
22 |
23 | service TestPB {
24 | rpc Add(AddRequest) returns (AddResponse);
25 | rpc Substr(SubstrRequest) returns (SubstrResponse);
26 | };
27 |
28 |
--------------------------------------------------------------------------------
/tools/templates/file/50x.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Error
5 |
12 |
13 |
14 | An error occurred.
15 | Sorry, the page you are looking for is currently unavailable.
16 | Please try again later.
17 | If you are the system administrator of this resource then you should check
18 | the srpc-ctl README.md for details.
19 | Faithfully yours, srpc.
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/message/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(message)
3 |
4 | include_directories(${CMAKE_CURRENT_BINARY_DIR})
5 |
6 | set(PROTO_LIST rpc_meta.proto rpc_meta_brpc.proto rpc_meta_trpc.proto)
7 | protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_LIST})
8 |
9 | set(SRC
10 | rpc_message_brpc.cc
11 | rpc_message_srpc.cc
12 | rpc_message_thrift.cc
13 | rpc_message_trpc.cc
14 | ${PROTO_SRCS} ${PROTO_HDRS}
15 | )
16 |
17 | add_library(${PROJECT_NAME} OBJECT ${SRC})
18 | if (WIN32)
19 | target_compile_definitions(
20 | ${PROJECT_NAME} PRIVATE
21 | strdup=_strdup
22 | strcasecmp=_stricmp
23 | strncasecmp=_strnicmp
24 | )
25 | endif ()
26 |
27 |
--------------------------------------------------------------------------------
/docs/docs-01-idl.md:
--------------------------------------------------------------------------------
1 | [English version](/docs/en/docs-01-idl.md)
2 |
3 | ## 01 - RPC IDL
4 | - 描述文件
5 | - 前后兼容
6 | - Protobuf/Thrift
7 |
8 | ### 示例
9 | 下面我们通过一个具体例子来呈现
10 | - 我们拿pb举例,定义一个ServiceName为``Example``的``example.proto``文件
11 | - rpc接口名为``Echo``,输入参数为``EchoRequest``,输出参数为``EchoResponse``
12 | - ``EchoRequest``包括两个string:``message``和``name``
13 | - ``EchoResponse``包括一个string:``message``
14 |
15 | ~~~proto
16 | syntax="proto2";
17 |
18 | message EchoRequest {
19 | optional string message = 1;
20 | optional string name = 2;
21 | };
22 |
23 | message EchoResponse {
24 | optional string message = 1;
25 | };
26 |
27 | service Example {
28 | rpc Echo(EchoRequest) returns (EchoResponse);
29 | };
30 | ~~~
31 |
32 |
--------------------------------------------------------------------------------
/benchmark/test.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 |
4 | #serverlist = [("srpc", "pb"), ("brpc", "pb"), ("thrift", "thrift")]
5 | serverlist = [("thrift", "thrift")]
6 | #reqlist = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768]
7 | parlist = [1, 2, 4, 8, 16, 32, 64, 128, 256]
8 |
9 | for server, idl in serverlist:
10 | #os.system("nohup ./server 8811 %s &" % server)
11 | for par in parlist:
12 | #for reqsize in reqlist:
13 | #cmd = "./echo_client %s" % reqsize
14 | #cmd = "./client 127.0.0.1 8811 %s %s 100 %s" % (server, idl, reqsize)
15 | cmd = "./client 127.0.0.1 8811 %s %s %s 1024" % (server, idl, par)
16 | print cmd
17 | os.system(cmd);
18 | time.sleep(1);
19 |
20 | #os.system("killall server")
21 |
22 |
--------------------------------------------------------------------------------
/tools/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 |
3 | project(srpc-ctl
4 | VERSION 0.10.3
5 | LANGUAGES C CXX
6 | )
7 |
8 | set(CMAKE_CXX_STANDARD 11)
9 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
10 | set(CMAKE_BUILD_TYPE RelWithDebInfo)
11 |
12 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
13 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
14 |
15 | set(generator_code
16 | "../src/generator/generator.cc"
17 | "../src/generator/parser.cc")
18 |
19 | set(srpc_ctl_code
20 | "srpc_ctl.cc"
21 | "srpc_config.cc"
22 | "srpc_controller.cc"
23 | "srpc_basic_controller.cc"
24 | "srpc_rpc_controller.cc"
25 | "srpc_proxy_controller.cc")
26 |
27 | include_directories("../src/")
28 | add_executable(srpc ${srpc_ctl_code} ${generator_code})
29 | target_link_libraries(srpc ${LIBRARY_NAME})
30 |
31 |
--------------------------------------------------------------------------------
/src/module/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(module)
3 |
4 | include_directories(${CMAKE_CURRENT_BINARY_DIR})
5 |
6 | set(PROTO_LIST
7 | proto/opentelemetry_common.proto
8 | proto/opentelemetry_resource.proto
9 | proto/opentelemetry_trace.proto
10 | proto/opentelemetry_metrics.proto
11 | proto/opentelemetry_metrics_service.proto)
12 |
13 | protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_LIST})
14 |
15 | set(SRC
16 | rpc_module.cc
17 | rpc_trace_module.cc
18 | rpc_metrics_module.cc
19 | rpc_trace_filter.cc
20 | rpc_metrics_filter.cc
21 | ${PROTO_SRCS} ${PROTO_HDRS}
22 | )
23 |
24 | add_library(${PROJECT_NAME} OBJECT ${SRC})
25 |
26 | if (WIN32)
27 | target_compile_definitions(
28 | ${PROJECT_NAME} PRIVATE
29 | strdup=_strdup
30 | strcasecmp=_stricmp
31 | strncasecmp=_strnicmp
32 | )
33 | endif ()
34 |
35 |
--------------------------------------------------------------------------------
/src/message/rpc_meta.proto:
--------------------------------------------------------------------------------
1 | syntax="proto2";
2 |
3 | message RPCMetaKeyValue {
4 | required string key = 1;
5 | oneof value
6 | {
7 | int32 int_value = 2;
8 | string str_value = 3;
9 | bytes bytes_value = 4;
10 | }
11 | };
12 |
13 | message RPCRequestMeta {
14 | optional string service_name = 1;
15 | optional string method_name = 2;
16 | optional int64 log_id = 3;
17 | };
18 |
19 | message RPCResponseMeta {
20 | optional int32 status_code = 1 [default = 0];
21 | optional int32 error = 2 [default = 0];
22 | };
23 |
24 | message RPCMeta {
25 | optional RPCRequestMeta request = 1;
26 | optional RPCResponseMeta response = 2;
27 | optional uint32 srpc_version = 3;
28 | optional int32 compress_type = 4 [default = 0];
29 | optional int32 origin_size = 5;
30 | optional int32 compressed_size = 6;
31 | optional int32 data_type = 7;
32 | repeated RPCMetaKeyValue trans_info = 8;
33 | };
34 |
--------------------------------------------------------------------------------
/docs/en/docs-01-idl.md:
--------------------------------------------------------------------------------
1 | [中文版](/docs/docs-01-idl.md)
2 |
3 | ## 01 - RPC IDL
4 |
5 | - Interface Description Languaue file
6 | - Backward and forward compatibility
7 | - Protobuf/Thrift
8 |
9 | ### Sample
10 |
11 | You can follow the detailed example below:
12 |
13 | - Take pb as an example. First, define an `example.proto` file with the ServiceName as `Example`.
14 | - The name of the rpc interface is `Echo`, with the input parameter as `EchoRequest`, and the output parameter as `EchoResponse`.
15 | - `EchoRequest` consists of two strings: `message` and `name`.
16 | - `EchoResponse` consists of one string: `message`.
17 |
18 | ~~~proto
19 | syntax="proto2";
20 |
21 | message EchoRequest {
22 | optional string message = 1;
23 | optional string name = 2;
24 | };
25 |
26 | message EchoResponse {
27 | optional string message = 1;
28 | };
29 |
30 | service Example {
31 | rpc Echo(EchoRequest) returns (EchoResponse);
32 | };
33 | ~~~
34 |
35 |
--------------------------------------------------------------------------------
/docs/docs-02-service.md:
--------------------------------------------------------------------------------
1 | [English version](/docs/en/docs-02-service.md)
2 |
3 | ## 02 - RPC Service
4 | - 组成SRPC服务的基本单元
5 | - 每一个Service一定由某一种IDL生成
6 | - Service只与IDL有关,与网络通信具体协议无关
7 |
8 | ### 示例
9 | 下面我们通过一个具体例子来呈现
10 | - 沿用上面的``example.proto``IDL描述文件
11 | - 执行官方的``protoc example.proto --cpp_out=./ --proto_path=./``获得``example.pb.h``和``example.pb.cpp``两个文件
12 | - 执行SRPC的``srpc_generator protobuf ./example.proto ./``获得``example.srpc.h``文件
13 | - 我们派生``Example::Service``来实现具体的rpc业务逻辑,这就是一个RPC Service
14 | - 注意这个Service没有任何网络、端口、通信协议等概念,仅仅负责完成实现从``EchoRequest``输入到输出``EchoResponse``的业务逻辑
15 |
16 | ~~~cpp
17 | class ExampleServiceImpl : public Example::Service
18 | {
19 | public:
20 | void Echo(EchoRequest *request, EchoResponse *response, RPCContext *ctx) override
21 | {
22 | response->set_message("Hi, " + request->name());
23 |
24 | printf("get_req:\n%s\nset_resp:\n%s\n",
25 | request->DebugString().c_str(),
26 | response->DebugString().c_str());
27 | }
28 | };
29 | ~~~
30 |
31 |
--------------------------------------------------------------------------------
/tutorial/GNUmakefile:
--------------------------------------------------------------------------------
1 | ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
2 | ALL_TARGETS := all clean
3 | MAKE_FILE := Makefile
4 |
5 | DEFAULT_BUILD_DIR := build.cmake
6 | BUILD_DIR := $(shell if [ -f $(MAKE_FILE) ]; then echo "."; else echo $(DEFAULT_BUILD_DIR); fi)
7 | CMAKE3 := $(shell if which cmake3>/dev/null ; then echo cmake3; else echo cmake; fi;)
8 |
9 | .PHONY: $(ALL_TARGETS)
10 |
11 | all:
12 | mkdir -p $(BUILD_DIR)
13 | ifeq ($(DEBUG),y)
14 | cd $(BUILD_DIR) && $(CMAKE3) -D CMAKE_BUILD_TYPE=Debug $(ROOT_DIR)
15 | else ifneq ("${Workflow_DIR}workflow", "workflow")
16 | cd $(BUILD_DIR) && $(CMAKE3) -DWorkflow_DIR:STRING=${Workflow_DIR} $(ROOT_DIR)
17 | else
18 | cd $(BUILD_DIR) && $(CMAKE3) $(ROOT_DIR)
19 | endif
20 | make -C $(BUILD_DIR) -f Makefile
21 |
22 | clean:
23 | ifeq ($(MAKE_FILE), $(wildcard $(MAKE_FILE)))
24 | -make -f Makefile clean
25 | else ifeq ($(DEFAULT_BUILD_DIR), $(wildcard $(DEFAULT_BUILD_DIR)))
26 | -make -C $(DEFAULT_BUILD_DIR) clean
27 | endif
28 | rm -rf $(DEFAULT_BUILD_DIR)
29 |
30 |
--------------------------------------------------------------------------------
/test/GNUmakefile:
--------------------------------------------------------------------------------
1 | ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
2 | ALL_TARGETS := all check clean
3 | MAKE_FILE := Makefile
4 |
5 | DEFAULT_BUILD_DIR := build.cmake
6 | BUILD_DIR := $(shell if [ -f $(MAKE_FILE) ]; then echo "."; else echo $(DEFAULT_BUILD_DIR); fi)
7 | CMAKE3 := $(shell if which cmake3 ; then echo cmake3; else echo cmake; fi;)
8 |
9 | .PHONY: $(ALL_TARGETS)
10 |
11 | all:
12 | mkdir -p $(BUILD_DIR)
13 | ifeq ($(DEBUG),y)
14 | cd $(BUILD_DIR) && $(CMAKE3) -D CMAKE_BUILD_TYPE=Debug $(ROOT_DIR)
15 | else ifneq ("${Workflow_DIR}workflow", "workflow")
16 | cd $(BUILD_DIR) && $(CMAKE3) -DWorkflow_DIR:STRING=${Workflow_DIR} $(ROOT_DIR)
17 | else
18 | cd $(BUILD_DIR) && $(CMAKE3) $(ROOT_DIR)
19 | endif
20 | make -C $(BUILD_DIR) -f Makefile
21 |
22 | check:
23 | mkdir -p $(BUILD_DIR)
24 | cd $(BUILD_DIR) && $(CMAKE3) $(ROOT_DIR)
25 | make -C $(BUILD_DIR) check CTEST_OUTPUT_ON_FAILURE=1
26 |
27 | clean:
28 | ifeq ($(MAKE_FILE), $(wildcard $(MAKE_FILE)))
29 | -make -f Makefile clean
30 | endif
31 | rm -rf $(DEFAULT_BUILD_DIR)
32 |
33 |
--------------------------------------------------------------------------------
/benchmark/GNUmakefile:
--------------------------------------------------------------------------------
1 | ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
2 | ALL_TARGETS := all clean
3 | MAKE_FILE := Makefile
4 |
5 | DEFAULT_BUILD_DIR := build.cmake
6 | BUILD_DIR := $(shell if [ -f $(MAKE_FILE) ]; then echo "."; else echo $(DEFAULT_BUILD_DIR); fi)
7 | CMAKE3 := $(shell if which cmake3>/dev/null ; then echo cmake3; else echo cmake; fi;)
8 |
9 | .PHONY: $(ALL_TARGETS)
10 |
11 | all:
12 | mkdir -p $(BUILD_DIR)
13 | ifeq ($(DEBUG),y)
14 | cd $(BUILD_DIR) && $(CMAKE3) -D CMAKE_BUILD_TYPE=Debug $(ROOT_DIR)
15 | else ifneq ("${Workflow_DIR}workflow", "workflow")
16 | cd $(BUILD_DIR) && $(CMAKE3) -DWorkflow_DIR:STRING=${Workflow_DIR} $(ROOT_DIR)
17 | else
18 | cd $(BUILD_DIR) && $(CMAKE3) $(ROOT_DIR)
19 | endif
20 | make -C $(BUILD_DIR) -f Makefile
21 |
22 | clean:
23 | ifeq ($(MAKE_FILE), $(wildcard $(MAKE_FILE)))
24 | -make -f Makefile clean
25 | else ifeq ($(DEFAULT_BUILD_DIR), $(wildcard $(DEFAULT_BUILD_DIR)))
26 | -make -C $(DEFAULT_BUILD_DIR) clean
27 | endif
28 | rm -rf $(DEFAULT_BUILD_DIR)
29 |
30 | #g++ -o thrift_server thrift_server.cc gen-cpp/*.cpp -O2 -g -lthrift -lthriftnb -levent -lpthread -std=c++11
31 |
--------------------------------------------------------------------------------
/tools/templates/basic/server_main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "workflow/WF%sServer.h"
4 | #include "workflow/WFFacilities.h"
5 |
6 | #include "config/util.h"
7 | #include "config/config.h"
8 |
9 | static WFFacilities::WaitGroup wait_group(1);
10 | static srpc::RPCConfig config;
11 |
12 | void sig_handler(int signo)
13 | {
14 | wait_group.done();
15 | }
16 |
17 | void init()
18 | {
19 | if (config.load("./server.conf") == false)
20 | {
21 | perror("Load config failed");
22 | exit(1);
23 | }
24 |
25 | signal(SIGINT, sig_handler);
26 | signal(SIGTERM, sig_handler);
27 | }
28 |
29 | void process(WF%sTask *task)
30 | {
31 | // delete the example codes and fill your logic
32 | %s
33 | }
34 |
35 | int main()
36 | {
37 | init();
38 |
39 | WF%sServer server(process);
40 |
41 | if (server.start(config.server_port()) == 0)
42 | {
43 | fprintf(stderr, "%s server started, port %%u\n", config.server_port());
44 | wait_group.wait();
45 | server.stop();
46 | }
47 | else
48 | perror("server start");
49 |
50 | return 0;
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/tools/templates/common/util.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "workflow/WFTaskFactory.h"
7 |
8 | template
9 | void print_peer_address(TASK *server_task)
10 | {
11 | char addrstr[128];
12 | struct sockaddr_storage addr;
13 | socklen_t l = sizeof addr;
14 | unsigned short port = 0;
15 | long long seq = server_task->get_task_seq();
16 |
17 | server_task->get_peer_addr((struct sockaddr *)&addr, &l);
18 | if (addr.ss_family == AF_INET)
19 | {
20 | struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
21 | inet_ntop(AF_INET, &sin->sin_addr, addrstr, 128);
22 | port = ntohs(sin->sin_port);
23 | }
24 | else if (addr.ss_family == AF_INET6)
25 | {
26 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
27 | inet_ntop(AF_INET6, &sin6->sin6_addr, addrstr, 128);
28 | port = ntohs(sin6->sin6_port);
29 | }
30 | else
31 | strcpy(addrstr, "Unknown");
32 |
33 | fprintf(stderr, "peer address: %s:%d, seq: %lld.\n", addrstr, port, seq);
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/third_party/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/$${HAVE_SYS_UIO_H_01}/true/g' $(<) | " +
10 | "sed 's/$${PROJECT_VERSION_MAJOR}/0/g' | " +
11 | "sed 's/$${PROJECT_VERSION_MINOR}/9/g' | " +
12 | "sed 's/$${PROJECT_VERSION_PATCH}/2/g' >$(@)",
13 | )
14 |
15 |
16 | cc_library(
17 | name = "snappy",
18 | srcs = [
19 | "snappy.cc",
20 | "snappy-c.cc",
21 | "snappy-sinksource.cc",
22 | "snappy-stubs-internal.cc",
23 | ],
24 | hdrs = [
25 | ":snappy_stubs_public_h",
26 | "snappy.h",
27 | "snappy-c.h",
28 | "snappy-internal.h",
29 | "snappy-sinksource.h",
30 | "snappy-stubs-internal.h",
31 | "snappy-stubs-public.h.in",
32 | ],
33 | copts = [
34 | "-Wno-non-virtual-dtor",
35 | "-Wno-unused-variable",
36 | "-Wno-implicit-fallthrough",
37 | "-Wno-unused-function",
38 | ],
39 | includes = ["."],
40 | visibility = ["//visibility:public"],
41 | )
42 |
--------------------------------------------------------------------------------
/tools/templates/common/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(%s LANGUAGES CXX)
3 | set(CMAKE_CXX_STANDARD 11)
4 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
5 | set(CMAKE_BUILD_TYPE RelWithDebInfo)
6 |
7 | # Find all the dependencies
8 | find_package(OpenSSL REQUIRED)
9 | set(Workflow_DIR "%s")
10 | find_package(Workflow REQUIRED CONFIG HINTS ${Workflow_DIR})
11 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
12 |
13 | # Prefer to static link first
14 | set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ${CMAKE_FIND_LIBRARY_SUFFIXES})
15 | find_library(Workflow_LIB workflow HINTS ${Workflow_DIR}/_lib)
16 |
17 | # Set all the libraries here
18 | set(LIB ${Workflow_LIB} pthread OpenSSL::SSL OpenSSL::Crypto)
19 |
20 | # Add all the common codes here
21 | set(COMMON_CODE config/config.cc config/Json.cc%s)
22 |
23 | # Add header directories and library directories here
24 | include_directories(${OPENSSL_INCLUDE_DIR} ${WORKFLOW_INCLUDE_DIR})
25 | link_directories(${OPENSSL_LINK_DIR} ${WORKFLOW_LIB_DIR})
26 |
27 | # Build executable outputs
28 | set(PROJECT_OUTPUT server%s)
29 | foreach(output ${PROJECT_OUTPUT})
30 | add_executable(${output} ${output}_main.cc ${COMMON_CODE})
31 | target_link_libraries(${output} ${LIB})
32 | endforeach()
33 |
34 |
--------------------------------------------------------------------------------
/src/module/proto/opentelemetry_resource.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2019, OpenTelemetry Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | package opentelemetry.proto.resource.v1;
18 |
19 | import "opentelemetry_common.proto";
20 |
21 | // Resource information.
22 | message Resource {
23 | // Set of attributes that describe the resource.
24 | // Attribute keys MUST be unique (it is not allowed to have more than one
25 | // attribute with the same key).
26 | repeated opentelemetry.proto.common.v1.KeyValue attributes = 1;
27 |
28 | // dropped_attributes_count is the number of dropped attributes. If the value is 0, then
29 | // no attributes were dropped.
30 | uint32 dropped_attributes_count = 2;
31 | }
32 |
--------------------------------------------------------------------------------
/WORKSPACE:
--------------------------------------------------------------------------------
1 | workspace(name = "srpc")
2 |
3 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
4 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
5 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
6 |
7 | http_archive(
8 | name = "rules_proto",
9 | sha256 = "d8992e6eeec276d49f1d4e63cfa05bbed6d4a26cfe6ca63c972827a0d141ea3b",
10 | strip_prefix = "rules_proto-cfdc2fa31879c0aebe31ce7702b1a9c8a4be02d2",
11 | urls = [
12 | "https://github.com/bazelbuild/rules_proto/archive/cfdc2fa31879c0aebe31ce7702b1a9c8a4be02d2.tar.gz",
13 | ],
14 | )
15 | load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
16 | rules_proto_dependencies()
17 | rules_proto_toolchains()
18 |
19 | git_repository(
20 | name = "workflow",
21 | commit = "2421bab69935ff3b2d01cb46f11051166333df65",
22 | remote = "https://github.com/sogou/workflow.git")
23 |
24 | new_git_repository(
25 | name = "lz4",
26 | build_file = "@//third_party:lz4.BUILD",
27 | tag = "v1.9.3",
28 | remote = "https://github.com/lz4/lz4.git")
29 |
30 | new_git_repository(
31 | name = "snappy",
32 | build_file = "@//third_party:snappy.BUILD",
33 | tag = "1.1.9",
34 | remote = "https://github.com/google/snappy.git")
35 |
36 |
--------------------------------------------------------------------------------
/tools/templates/basic/client_main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "workflow/%sMessage.h"
4 | #include "workflow/WFTaskFactory.h"
5 | #include "workflow/WFFacilities.h"
6 |
7 | #include "config/config.h"
8 |
9 | static WFFacilities::WaitGroup wait_group(1);
10 | static srpc::RPCConfig config;
11 |
12 | void sig_handler(int signo)
13 | {
14 | wait_group.done();
15 | }
16 |
17 | void init()
18 | {
19 | if (config.load("./client.conf") == false)
20 | {
21 | perror("Load config failed");
22 | exit(1);
23 | }
24 |
25 | signal(SIGINT, sig_handler);
26 | signal(SIGTERM, sig_handler);
27 | }
28 |
29 | void callback(WF%sTask *task)
30 | {
31 | int state = task->get_state();
32 | int error = task->get_error();
33 | fprintf(stderr, "%s client state = %%d error = %%d\n", state, error);
34 | %s
35 | }
36 |
37 | int main()
38 | {
39 | init();
40 |
41 | std::string url = std::string("%s://") + %sconfig.client_host() +
42 | std::string(":") + std::to_string(config.client_port());
43 |
44 | WF%sTask *task = WFTaskFactory::create_%s_task(url,%s
45 | config.retry_max(),
46 | callback);
47 | %s
48 | task->start();
49 |
50 | wait_group.wait();
51 | return 0;
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/docs/en/docs-02-service.md:
--------------------------------------------------------------------------------
1 | [中文版](/docs/docs-02-service.md)
2 |
3 | ## 02 - RPC Service
4 |
5 | - It is the basic unit for SRPC services.
6 | - Each service must be generated by one type of IDLs.
7 | - Service is determined by IDL type, not by specific network communication protocol.
8 |
9 | ### Sample
10 |
11 | You can follow the detailed example below:
12 |
13 | - Use the same `example.proto` IDL above.
14 | - Run the official `protoc example.proto --cpp_out=./ --proto_path=./` to get two files: `example.pb.h` and `example.pb.cpp`.
15 | - Run the `srpc_generator protobuf ./example.proto ./` in SRPC to get `example.srpc.h`.
16 | - Derive `Example::Service` to implement the rpc business logic, which is an RPC Service.
17 | - Please note that this Service does not involve any concepts such as network, port, communication protocol, etc., and it is only responsible for completing the business logic that convert `EchoRequest` to `EchoResponse`.
18 |
19 | ~~~cpp
20 | class ExampleServiceImpl : public Example::Service
21 | {
22 | public:
23 | void Echo(EchoRequest *request, EchoResponse *response, RPCContext *ctx) override
24 | {
25 | response->set_message("Hi, " + request->name());
26 |
27 | printf("get_req:\n%s\nset_resp:\n%s\n",
28 | request->DebugString().c_str(),
29 | response->DebugString().c_str());
30 | }
31 | };
32 | ~~~
33 |
34 |
--------------------------------------------------------------------------------
/src/http/http_server.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2023 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_HTTP_SERVER_H__
18 | #define __RPC_HTTP_SERVER_H__
19 |
20 | #include "workflow/WFHttpServer.h"
21 | #include "rpc_basic.h"
22 | #include "rpc_filter.h"
23 | #include "rpc_module.h"
24 |
25 | namespace srpc
26 | {
27 |
28 | class HttpServer : public WFHttpServer
29 | {
30 | public:
31 | HttpServer(http_process_t proc) :
32 | WFHttpServer(std::move(proc)),
33 | listen_port(0)
34 | {
35 | }
36 |
37 | void add_filter(RPCFilter *filter);
38 |
39 | protected:
40 | CommSession *new_session(long long seq, CommConnection *conn) override;
41 |
42 | private:
43 | unsigned short get_listen_port();
44 |
45 | private:
46 | std::mutex mutex;
47 | RPCModule *modules[SRPC_MODULE_MAX] = { NULL };
48 | unsigned short listen_port;
49 | };
50 |
51 | } // namespace srpc
52 |
53 | #endif
54 |
55 |
--------------------------------------------------------------------------------
/tools/templates/rpc/server_thrift.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "workflow/WFFacilities.h"
5 | #include "srpc/rpc_types.h"
6 |
7 | #include "config/config.h"
8 | #include "%s.srpc.h"
9 |
10 | using namespace srpc;
11 |
12 | static WFFacilities::WaitGroup wait_group(1);
13 | static srpc::RPCConfig config;
14 |
15 | void sig_handler(int signo)
16 | {
17 | wait_group.done();
18 | }
19 |
20 | void init()
21 | {
22 | if (config.load("./server.conf") == false)
23 | {
24 | perror("Load config failed");
25 | exit(1);
26 | }
27 | }
28 |
29 | class ServiceImpl : public %s::Service
30 | {
31 | public:
32 | void Echo(EchoResult& _return, const std::string& message) override
33 | {
34 | %s// 4. delete the following codes and fill your logic
35 | fprintf(stderr, "get req. %%s\n", message.c_str());
36 | _return.message = "Hi back.";
37 | }
38 | };
39 |
40 | int main()
41 | {
42 | // 1. load config
43 | init();
44 |
45 | // 2. start server
46 | %sServer server;
47 | ServiceImpl impl;
48 | server.add_service(&impl);
49 |
50 | config.load_filter(server);
51 |
52 | if (server.start(config.server_port()) == 0)
53 | {
54 | // 3. success and wait
55 | printf("%s %s server started, port %%u\n", config.server_port());
56 | wait_group.wait();
57 | server.stop();
58 | }
59 | else
60 | perror("server start");
61 |
62 | return 0;
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/src/compress/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(compress)
3 |
4 | set(SRC
5 | rpc_compress.cc
6 | rpc_compress_snappy.cc
7 | )
8 |
9 | set_property(SOURCE rpc_compress_snappy.cc APPEND PROPERTY COMPILE_OPTIONS "-fno-rtti")
10 |
11 | if (WITH_VCPKG_TOOLCHAIN)
12 | add_library(${PROJECT_NAME} OBJECT ${SRC})
13 | target_link_libraries(${PROJECT_NAME} lz4 snappy)
14 | else ()
15 | if (SNAPPY_INSTALLED)
16 | set(SNAPPY_LIB snappy)
17 | else ()
18 | set(SNAPPY_SRC
19 | ../../third_party/snappy/config.h
20 | ../../third_party/snappy/snappy-internal.h
21 | ../../third_party/snappy/snappy-sinksource.cc
22 | ../../third_party/snappy/snappy-sinksource.h
23 | ../../third_party/snappy/snappy-stubs-internal.cc
24 | ../../third_party/snappy/snappy-stubs-internal.h
25 | ../../third_party/snappy/snappy-stubs-public.h
26 | ../../third_party/snappy/snappy.cc
27 | ../../third_party/snappy/snappy.h
28 | )
29 | endif ()
30 |
31 | if (LZ4_INSTALLED)
32 | set(LZ4_LIB lz4)
33 | else ()
34 | set(LZ4_SRC
35 | ../../third_party/lz4/lib/lz4.c
36 | ../../third_party/lz4/lib/lz4.h
37 | ../../third_party/lz4/lib/lz4hc.h
38 | ../../third_party/lz4/lib/lz4hc.c
39 | ../../third_party/lz4/lib/lz4frame.h
40 | ../../third_party/lz4/lib/lz4frame.c
41 | ../../third_party/lz4/lib/xxhash.c
42 | ../../third_party/lz4/lib/xxhash.h
43 | )
44 | endif ()
45 |
46 | add_library(
47 | ${PROJECT_NAME} OBJECT
48 | ${SRC}
49 | ${SNAPPY_SRC}
50 | ${LZ4_SRC}
51 | )
52 | endif()
53 |
54 |
--------------------------------------------------------------------------------
/src/http/http_module.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2023 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_HTTP_MODULE_H__
18 | #define __RPC_HTTP_MODULE_H__
19 |
20 | #include "rpc_basic.h"
21 | #include "rpc_module.h"
22 | #include "rpc_trace_module.h"
23 | #include "rpc_metrics_module.h"
24 |
25 | namespace srpc
26 | {
27 |
28 | class HttpTraceModule : public TraceModule
29 | {
30 | public:
31 | bool client_begin(SubTask *task, RPCModuleData& data) override;
32 | bool client_end(SubTask *task, RPCModuleData& data) override;
33 | bool server_begin(SubTask *task, RPCModuleData& data) override;
34 | bool server_end(SubTask *task, RPCModuleData& data) override;
35 | };
36 |
37 | class HttpMetricsModule : public MetricsModule
38 | {
39 | public:
40 | bool client_begin(SubTask *task, RPCModuleData& data) override;
41 | bool server_begin(SubTask *task, RPCModuleData& data) override;
42 | };
43 |
44 | using HttpCustomModule = CustomModule;
45 |
46 | } // end namespace srpc
47 |
48 | #endif
49 |
50 |
--------------------------------------------------------------------------------
/tools/templates/rpc/server_protobuf.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "workflow/WFFacilities.h"
5 | #include "srpc/rpc_types.h"
6 |
7 | #include "config/config.h"
8 | #include "%s.srpc.h"
9 |
10 | using namespace srpc;
11 |
12 | static WFFacilities::WaitGroup wait_group(1);
13 | static srpc::RPCConfig config;
14 |
15 | void sig_handler(int signo)
16 | {
17 | wait_group.done();
18 | }
19 |
20 | void init()
21 | {
22 | if (config.load("./server.conf") == false)
23 | {
24 | perror("Load config failed");
25 | exit(1);
26 | }
27 |
28 | signal(SIGINT, sig_handler);
29 | signal(SIGTERM, sig_handler);
30 | }
31 |
32 | class ServiceImpl : public %s::Service
33 | {
34 | public:
35 | void Echo(EchoRequest *req, EchoResponse *resp, RPCContext *ctx) override
36 | {
37 | %s// 4. delete the following codes and fill your logic
38 | fprintf(stderr, "get req. %%s\n", req->DebugString().c_str());
39 | resp->set_message("Hi back");
40 | }
41 | };
42 |
43 | int main()
44 | {
45 | // 1. load config
46 | init();
47 |
48 | // 2. start server
49 | %sServer server;
50 | ServiceImpl impl;
51 | server.add_service(&impl);
52 |
53 | config.load_filter(server);
54 |
55 | if (server.start(config.server_port()) == 0)
56 | {
57 | // 3. success and wait
58 | fprintf(stderr, "%s %s server started, port %%u\n", config.server_port());
59 | wait_group.wait();
60 | server.stop();
61 | }
62 | else
63 | perror("server start");
64 |
65 | return 0;
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/tools/templates/file/server_main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "workflow/HttpMessage.h"
4 | #include "workflow/HttpUtil.h"
5 | #include "workflow/WFHttpServer.h"
6 | #include "workflow/WFFacilities.h"
7 |
8 | #include "config/config.h"
9 | #include "file_service.h"
10 |
11 | using namespace protocol;
12 |
13 | static WFFacilities::WaitGroup wait_group(1);
14 | static srpc::RPCConfig config;
15 |
16 | void sig_handler(int signo)
17 | {
18 | wait_group.done();
19 | }
20 |
21 | void init()
22 | {
23 | if (config.load("./server.conf") == false)
24 | {
25 | perror("Load config failed");
26 | exit(1);
27 | }
28 |
29 | signal(SIGINT, sig_handler);
30 | }
31 |
32 | int main()
33 | {
34 | init();
35 |
36 | unsigned short port = config.server_port();
37 | const char *cert_file = config.server_cert_file();
38 | const char *file_key = config.server_file_key();
39 |
40 | FileService service(config.get_root_path(), config.get_error_page());
41 | auto&& proc = std::bind(&FileService::process, &service,
42 | std::placeholders::_1);
43 |
44 | int ret;
45 | WFHttpServer server(proc);
46 |
47 | if (strlen(cert_file) != 0 && strlen(file_key) != 0)
48 | ret = server.start(port, cert_file, file_key);
49 | else
50 | ret = server.start(port);
51 |
52 | if (ret == 0)
53 | {
54 | fprintf(stderr, "http file service start, port %u\n", port);
55 | wait_group.wait();
56 | server.stop();
57 | }
58 | else
59 | perror("http file service start");
60 |
61 | return 0;
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/src/rpc_global.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_GLOBAL_H__
18 | #define __RPC_GLOBAL_H__
19 |
20 | #include
21 | #include
22 | #include "rpc_options.h"
23 | #include "rpc_module.h"
24 |
25 | namespace srpc
26 | {
27 |
28 | class SRPCGlobal
29 | {
30 | public:
31 | static SRPCGlobal *get_instance()
32 | {
33 | static SRPCGlobal kInstance;
34 |
35 | return &kInstance;
36 | }
37 |
38 | public:
39 | const char *get_srpc_version() const;
40 |
41 | bool task_init(RPCClientParams& params, ParsedURI& uri,
42 | struct sockaddr_storage *ss, socklen_t *ss_len) const;
43 |
44 | unsigned long long get_random();
45 | void set_group_id(unsigned short id) { this->group_id = id; }
46 | void set_machine_id(unsigned short id) { this->machine_id = id; }
47 |
48 | private:
49 | SRPCGlobal();
50 | SnowFlake snowflake;
51 | std::random_device rd;
52 | std::mt19937 gen;
53 | unsigned short group_id;
54 | unsigned short machine_id;
55 | };
56 |
57 | } // namespace srpc
58 |
59 | #endif
60 |
61 |
--------------------------------------------------------------------------------
/benchmark/thrift_server.cc:
--------------------------------------------------------------------------------
1 | #include "gen-cpp/BenchmarkThrift.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | using namespace ::apache::thrift;
10 | using namespace ::apache::thrift::protocol;
11 | using namespace ::apache::thrift::transport;
12 | using namespace ::apache::thrift::server;
13 | using namespace ::apache::thrift::concurrency;
14 |
15 | using boost::shared_ptr;
16 |
17 | class BenchmarkThriftHandler : virtual public BenchmarkThriftIf {
18 | public:
19 | void echo_thrift(const std::string& msg) { }
20 | void slow_thrift(const std::string& msg) {
21 | usleep(15000);
22 | }
23 | };
24 |
25 | int main(int argc, char **argv) {
26 | int port = 8811;
27 | shared_ptr handler(new BenchmarkThriftHandler());
28 | shared_ptr processor(new BenchmarkThriftProcessor(handler));
29 | shared_ptr protocolFactory(new TBinaryProtocolFactory());
30 | boost::shared_ptr threadManager = ThreadManager::newSimpleThreadManager(16);
31 | boost::shared_ptr threadFactory = boost::shared_ptr(new PosixThreadFactory());
32 |
33 | TNonblockingServer server(processor, protocolFactory, port, threadManager);
34 | server.setMaxConnections(2048);
35 | server.setNumIOThreads(16);
36 | threadManager->threadFactory(threadFactory);
37 | threadManager->start();
38 | server.serve();
39 | return 0;
40 | }
41 |
--------------------------------------------------------------------------------
/tools/templates/file/file_service.h:
--------------------------------------------------------------------------------
1 | #ifndef _RPC_FILE_SERVICE_H_
2 | #define _RPC_FILE_SERVICE_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include "workflow/Workflow.h"
8 | #include "workflow/HttpMessage.h"
9 | #include "workflow/HttpUtil.h"
10 | #include "workflow/WFHttpServer.h"
11 | #include "workflow/WFFacilities.h"
12 |
13 | // This is a simple exmaple for file service
14 |
15 | class FileService
16 | {
17 | public:
18 | using ErrorPageMap = std::unordered_map;
19 |
20 | void process(WFHttpTask *server_task);
21 | void pread_callback(WFFileIOTask *task);
22 | protected:
23 | struct ModuleCtx
24 | {
25 | protocol::HttpResponse *resp;
26 | void *buf;
27 | bool is_error_set;
28 | ModuleCtx(protocol::HttpResponse * resp) :
29 | resp(resp),
30 | buf(NULL),
31 | is_error_set(false)
32 | {
33 | }
34 | };
35 |
36 | private:
37 | WFModuleTask *create_module(WFHttpTask *task, const std::string& path);
38 | SubTask *create_file_task(const std::string& path, struct ModuleCtx *ctx);
39 | SubTask *create_error_task(int code, struct ModuleCtx *ctx);
40 |
41 | public:
42 | FileService(std::string root, const ErrorPageMap& error_page) :
43 | root(std::move(root)),
44 | error_page(error_page)
45 | {
46 | if (this->root.empty())
47 | root = "./";
48 | else if (this->root.at(this->root.length() - 1) != '/')
49 | root += "/";
50 | }
51 |
52 | private:
53 | std::string root;
54 | const ErrorPageMap& error_page;
55 | };
56 |
57 | #endif
58 |
59 |
--------------------------------------------------------------------------------
/tools/templates/config/config_simple.h:
--------------------------------------------------------------------------------
1 | #ifndef _RPC_CONFIG_H_
2 | #define _RPC_CONFIG_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include "Json.h"
8 |
9 | namespace srpc
10 | {
11 |
12 | class RPCConfig
13 | {
14 | public:
15 | using ErrorPageMap = std::unordered_map;
16 |
17 | bool load(const char *file);
18 |
19 | unsigned short server_port() const { return this->s_port; }
20 | const char *server_cert_file() const { return this->s_cert_file.c_str(); }
21 | const char *server_file_key() const { return this->s_file_key.c_str(); }
22 | unsigned short client_port() const { return this->c_port; }
23 | const char *client_host() const { return this->c_host.c_str(); }
24 | int redirect_max() const { return this->c_redirect_max; }
25 | int retry_max() const { return this->c_retry_max; }
26 | const char *client_user_name() const { return this->c_user_name.c_str(); }
27 | const char *client_password() const { return this->c_password.c_str(); }
28 | const char *get_root_path() const { return this->root_path.c_str(); }
29 | const ErrorPageMap& get_error_page() const { return this->error_page; }
30 |
31 | public:
32 | RPCConfig() : s_port(0), c_port(0), c_redirect_max(0), c_retry_max(0) { }
33 | ~RPCConfig();
34 |
35 | private:
36 | void load_server();
37 | void load_client();
38 |
39 | wfrest::Json data;
40 | unsigned short s_port;
41 | std::string s_cert_file;
42 | std::string s_file_key;
43 | std::string c_host;
44 | unsigned short c_port;
45 | int c_redirect_max;
46 | int c_retry_max;
47 | std::string c_user_name;
48 | std::string c_password;
49 | std::string root_path;
50 | ErrorPageMap error_page;
51 | };
52 |
53 | }
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/src/module/proto/opentelemetry_metrics_service.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2019, OpenTelemetry Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | package opentelemetry.proto.collector.metrics.v1;
18 |
19 | import "opentelemetry_metrics.proto";
20 |
21 | // Service that can be used to push metrics between one Application
22 | // instrumented with OpenTelemetry and a collector, or between a collector and a
23 | // central collector.
24 | service MetricsService {
25 | // For performance reasons, it is recommended to keep this RPC
26 | // alive for the entire life of the application.
27 | rpc Export(ExportMetricsServiceRequest) returns (ExportMetricsServiceResponse) {}
28 | }
29 |
30 | message ExportMetricsServiceRequest {
31 | // An array of ResourceMetrics.
32 | // For data coming from a single resource this array will typically contain one
33 | // element. Intermediary nodes (such as OpenTelemetry Collector) that receive
34 | // data from multiple origins typically batch the data before forwarding further and
35 | // in that case this array will contain multiple elements.
36 | repeated opentelemetry.proto.metrics.v1.ResourceMetrics resource_metrics = 1;
37 | }
38 |
39 | message ExportMetricsServiceResponse {
40 | }
41 |
--------------------------------------------------------------------------------
/CMakeLists_Headers.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 |
3 | set(SRC_HEADERS
4 | src/compress/rpc_compress.h
5 | src/compress/rpc_compress_gzip.h
6 | src/message/rpc_message.h
7 | src/message/rpc_message_srpc.h
8 | src/message/rpc_message_thrift.h
9 | src/message/rpc_message_brpc.h
10 | src/message/rpc_message_trpc.h
11 | src/thrift/rpc_thrift_buffer.h
12 | src/thrift/rpc_thrift_enum.h
13 | src/thrift/rpc_thrift_idl.h
14 | src/thrift/rpc_thrift_idl.inl
15 | src/var/ckms_quantiles.h
16 | src/var/time_window_quantiles.h
17 | src/var/rpc_var.h
18 | src/module/rpc_module.h
19 | src/module/rpc_trace_module.h
20 | src/module/rpc_metrics_module.h
21 | src/module/rpc_filter.h
22 | src/module/rpc_trace_filter.h
23 | src/module/rpc_metrics_filter.h
24 | src/rpc_basic.h
25 | src/rpc_buffer.h
26 | src/rpc_client.h
27 | src/rpc_context.h
28 | src/rpc_context.inl
29 | src/rpc_global.h
30 | src/rpc_options.h
31 | src/rpc_server.h
32 | src/rpc_service.h
33 | src/rpc_task.inl
34 | src/rpc_types.h
35 | src/rpc_zero_copy_stream.h
36 | src/rpc_define.h
37 | )
38 |
39 | if (NOT WIN32)
40 | set(SRC_HEADERS
41 | ${SRC_HEADERS}
42 | src/http/http_task.h
43 | src/http/http_module.h
44 | src/http/http_client.h
45 | src/http/http_server.h
46 | )
47 | endif ()
48 |
49 | if (NOT SNAPPY_INSTALLED)
50 | set(SNAPPY_HEADERS
51 | third_party/snappy/snappy.h
52 | third_party/snappy/snappy-c.h
53 | third_party/snappy/snappy-sinksource.h
54 | third_party/snappy/snappy-stubs-public.h
55 | )
56 | endif ()
57 |
58 | if (NOT LZ4_INSTALLED)
59 | set(LZ4_HEADERS
60 | third_party/lz4/lib/lz4.h
61 | third_party/lz4/lib/lz4frame.h
62 | )
63 | endif ()
64 |
65 | if (WITH_VCPKG_TOOLCHAIN)
66 | set(INCLUDE_HEADERS ${SRC_HEADERS})
67 | else()
68 | set(INCLUDE_HEADERS ${SRC_HEADERS} ${SNAPPY_HEADERS} ${LZ4_HEADERS})
69 | endif()
70 |
71 |
--------------------------------------------------------------------------------
/tutorial/tutorial-07-thrift_thrift_server.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "echo_thrift.srpc.h"
19 | #include "workflow/WFFacilities.h"
20 |
21 | using namespace srpc;
22 |
23 | static WFFacilities::WaitGroup wait_group(1);
24 |
25 | class ExampleServiceImpl : public Example::Service
26 | {
27 | public:
28 | void Echo(EchoResult& _return, const std::string& message,
29 | const std::string& name) override
30 | {
31 | _return.message = "Hi back, " + name;
32 |
33 | printf("Server Echo()\nreq_message:\n%s\nresp_message:\n%s\n",
34 | message.c_str(), _return.message.c_str());
35 | }
36 | };
37 |
38 | static void sig_handler(int signo)
39 | {
40 | wait_group.done();
41 | }
42 |
43 | int main()
44 | {
45 | signal(SIGINT, sig_handler);
46 | signal(SIGTERM, sig_handler);
47 |
48 | ThriftServer server;
49 | ExampleServiceImpl impl;
50 |
51 | server.add_service(&impl);
52 |
53 | if (server.start(1412) == 0)
54 | {
55 | printf("SRPC framework Thrift protocol server with thrift IDL is running on 1412\n"
56 | "Try ./thrift_thrift_client to send requests.\n\n");
57 | wait_group.wait();
58 | server.stop();
59 | }
60 | else
61 | perror("server start");
62 |
63 | return 0;
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/tools/templates/rpc/client_protobuf.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include "workflow/WFFacilities.h"
3 | #include "srpc/rpc_types.h"
4 | #include "%s.srpc.h"
5 | #include "config/config.h"
6 |
7 | using namespace srpc;
8 |
9 | static WFFacilities::WaitGroup wait_group(1);
10 | static srpc::RPCConfig config;
11 |
12 | void init()
13 | {
14 | if (config.load("./client.conf") == false)
15 | {
16 | perror("Load config failed");
17 | exit(1);
18 | }
19 | }
20 |
21 | int main()
22 | {
23 | // 1. load config
24 | init();
25 |
26 | // 2. start client
27 | RPCClientParams params = RPC_CLIENT_PARAMS_DEFAULT;
28 | params.host = config.client_host();
29 | params.port = config.client_port();
30 | %s
31 | %s::%sClient client(¶ms);
32 | config.load_filter(client);
33 |
34 | // 3. request with sync api
35 | EchoRequest req;
36 | EchoResponse resp;
37 | RPCSyncContext ctx;
38 |
39 | req.set_message("Hello, this is sync request!");
40 | client.Echo(&req, &resp, &ctx);
41 |
42 | if (ctx.success)
43 | fprintf(stderr, "sync resp. %%s\n", resp.DebugString().c_str());
44 | else
45 | fprintf(stderr, "sync status[%%d] error[%%d] errmsg:%%s\n",
46 | ctx.status_code, ctx.error, ctx.errmsg.c_str());
47 |
48 | // 4. request with async api
49 |
50 | req.set_message("Hello, this is async request!");
51 |
52 | client.Echo(&req, [](EchoResponse *resp, RPCContext *ctx) {
53 | if (ctx->success())
54 | fprintf(stderr, "async resp. %%s\n", resp->DebugString().c_str());
55 | else
56 | fprintf(stderr, "async status[%%d] error[%%d] errmsg:%%s\n",
57 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
58 | wait_group.done();
59 | });
60 |
61 | wait_group.wait();
62 |
63 | return 0;
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/tutorial/tutorial-02-srpc_pb_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "workflow/WFFacilities.h"
19 | #include "echo_pb.srpc.h"
20 | #include "srpc/rpc_types.h"
21 |
22 | using namespace srpc;
23 |
24 | static WFFacilities::WaitGroup wait_group(1);
25 |
26 | int main()
27 | {
28 | Example::SRPCClient client("127.0.0.1", 1412);
29 |
30 | //async
31 | EchoRequest req;
32 | req.set_message("Hello, srpc!");
33 | req.set_name("1412");
34 |
35 | client.Echo(&req, [](EchoResponse *resp, RPCContext *ctx) {
36 | if (ctx->success())
37 | printf("%s\n", resp->DebugString().c_str());
38 | else
39 | printf("status[%d] error[%d] errmsg:%s\n",
40 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
41 | wait_group.done();
42 | });
43 |
44 | //sync
45 | EchoRequest sync_req;
46 | EchoResponse sync_resp;
47 | RPCSyncContext sync_ctx;
48 |
49 | sync_req.set_message("Hello, srpc!");
50 | sync_req.set_name("Sync");
51 | client.Echo(&sync_req, &sync_resp, &sync_ctx);
52 | if (sync_ctx.success)
53 | printf("%s\n", sync_resp.DebugString().c_str());
54 | else
55 | printf("status[%d] error[%d] errmsg:%s\n",
56 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
57 |
58 | wait_group.wait();
59 | return 0;
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/tutorial/tutorial-01-srpc_pb_server.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "echo_pb.srpc.h"
19 | #include "workflow/WFFacilities.h"
20 | #include "srpc/rpc_types.h"
21 |
22 | using namespace srpc;
23 |
24 | static WFFacilities::WaitGroup wait_group(1);
25 |
26 | class ExampleServiceImpl : public Example::Service
27 | {
28 | public:
29 | void Echo(EchoRequest *req, EchoResponse *resp, RPCContext *ctx) override
30 | {
31 | resp->set_message("Hi back");
32 |
33 | printf("Server Echo()\nget_req:\n%s\nset_resp:\n%s\n",
34 | req->DebugString().c_str(), resp->DebugString().c_str());
35 | }
36 | };
37 |
38 | static void sig_handler(int signo)
39 | {
40 | wait_group.done();
41 | }
42 |
43 | int main()
44 | {
45 | GOOGLE_PROTOBUF_VERIFY_VERSION;
46 | signal(SIGINT, sig_handler);
47 | signal(SIGTERM, sig_handler);
48 |
49 | SRPCServer server;
50 | ExampleServiceImpl impl;
51 |
52 | server.add_service(&impl);
53 |
54 | if (server.start(1412) == 0)
55 | {
56 | printf("SRPC framework SRPC Protobuf server is running on 1412\n"
57 | "Try ./srpc_pb_client to send requests.\n\n");
58 | wait_group.wait();
59 | server.stop();
60 | }
61 | else
62 | perror("server start");
63 |
64 | google::protobuf::ShutdownProtobufLibrary();
65 | return 0;
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/tools/templates/rpc/client_thrift.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include "workflow/WFFacilities.h"
3 | #include "srpc/rpc_types.h"
4 | #include "%s.srpc.h"
5 | #include "config/config.h"
6 |
7 | using namespace srpc;
8 |
9 | static WFFacilities::WaitGroup wait_group(1);
10 | static srpc::RPCConfig config;
11 |
12 | void init()
13 | {
14 | if (config.load("./client.conf") == false)
15 | {
16 | perror("Load config failed");
17 | exit(1);
18 | }
19 | }
20 |
21 | int main()
22 | {
23 | // 1. load config
24 | init();
25 |
26 | // 2. start client
27 | RPCClientParams params = RPC_CLIENT_PARAMS_DEFAULT;
28 | params.host = config.client_host();
29 | params.port = config.client_port();
30 | %s
31 | %s::%sClient client(¶ms);
32 | config.load_filter(client);
33 |
34 | // 3. request with sync api
35 | EchoResult res;
36 |
37 | client.Echo(res, "Hello, this is sync request!");
38 |
39 | if (client.thrift_last_sync_success())
40 | fprintf(stderr, "sync resp. %%s\n", res.message.c_str());
41 | else
42 | {
43 | const auto& sync_ctx = client.thrift_last_sync_ctx();
44 |
45 | fprintf(stderr, "sync status[%%d] error[%%d] errmsg:%%s\n",
46 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
47 | }
48 |
49 | // 4. request with async api
50 | %s::EchoRequest req;
51 | req.message = "Hello, this is async request!";
52 |
53 | client.Echo(&req, [](%s::EchoResponse *resp, RPCContext *ctx) {
54 | if (ctx->success())
55 | fprintf(stderr, "async resp. %%s\n", resp->result.message.c_str());
56 | else
57 | fprintf(stderr, "async status[%%d] error[%%d] errmsg:%%s\n",
58 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
59 | wait_group.done();
60 | });
61 |
62 | wait_group.wait();
63 |
64 | return 0;
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/tutorial/tutorial-03-srpc_thrift_server.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "echo_thrift.srpc.h"
19 | #include "workflow/WFFacilities.h"
20 |
21 | using namespace srpc;
22 |
23 | static WFFacilities::WaitGroup wait_group(1);
24 |
25 | class ExampleServiceImpl : public Example::Service
26 | {
27 | public:
28 | void Echo(EchoResult& _return, const std::string& message,
29 | const std::string& name) override
30 | {
31 | _return.message = "Hi back, " + name;
32 |
33 | printf("Server Echo()\nreq_message:\n%s\nresp_message:\n%s\n",
34 | message.c_str(), _return.message.c_str());
35 | }
36 | };
37 |
38 | static void sig_handler(int signo)
39 | {
40 | wait_group.done();
41 | }
42 |
43 | int main()
44 | {
45 | GOOGLE_PROTOBUF_VERIFY_VERSION;
46 | signal(SIGINT, sig_handler);
47 | signal(SIGTERM, sig_handler);
48 |
49 | SRPCServer server;
50 | ExampleServiceImpl impl;
51 |
52 | server.add_service(&impl);
53 |
54 | if (server.start(1412) == 0)
55 | {
56 | printf("SRPC framework SRPC protocol server with thrift IDL is running on 1412\n"
57 | "Try ./srpc_thrift_client to send requests.\n\n");
58 | wait_group.wait();
59 | server.stop();
60 | }
61 | else
62 | perror("server start");
63 |
64 | google::protobuf::ShutdownProtobufLibrary();
65 | return 0;
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/docs/docs-04-client.md:
--------------------------------------------------------------------------------
1 | [English version](/docs/en/docs-04-client.md)
2 |
3 | ## 04 - RPC Client
4 | - 每一个Client对应着一个确定的目标/一个确定的集群
5 | - 每一个Client对应着一个确定的网络通信协议
6 | - 每一个Client对应着一个确定的IDL
7 |
8 | ### 示例
9 | 下面我们通过一个具体例子来呈现
10 | - 沿用上面的例子,client相对简单,直接调用即可
11 | - 通过``Example::XXXClient``创建某种RPC的client实例,需要目标的ip+port或url
12 | - 利用client实例直接调用rpc函数``Echo``即可,这是一次异步请求,请求完成后会进入回调函数
13 | - 具体的RPC Context用法请看下一个段落
14 |
15 | ~~~cpp
16 | #include
17 | #include "example.srpc.h"
18 | #include "workflow/WFFacilities.h"
19 |
20 | using namespace srpc;
21 |
22 | int main()
23 | {
24 | Example::SRPCClient client("127.0.0.1", 1412);
25 | EchoRequest req;
26 | req.set_message("Hello!");
27 | req.set_name("SRPCClient");
28 |
29 | WFFacilities::WaitGroup wait_group(1);
30 |
31 | client.Echo(&req, [&wait_group](EchoResponse *response, RPCContext *ctx) {
32 | if (ctx->success())
33 | printf("%s\n", response->DebugString().c_str());
34 | else
35 | printf("status[%d] error[%d] errmsg:%s\n",
36 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
37 | wait_group.done();
38 | });
39 |
40 | wait_group.wait();
41 | return 0;
42 | }
43 | ~~~
44 |
45 | ### 启动参数
46 |
47 | Client可以直接通过传入ip、port启动,或者通过参数启动。
48 |
49 | 上面的例子:
50 |
51 | ~~~cpp
52 | Example::SRPCClient client("127.0.0.1", 1412);
53 | ~~~
54 |
55 | 等同于:
56 |
57 | ~~~cpp
58 | struct RPCClientParams param = RPC_CLIENT_PARAMS_DEFAULT;
59 | param.host = "127.0.0.1";
60 | param.port = 1412;
61 | Example::SRPCClient client(¶m);
62 | ~~~
63 |
64 | 也等同于:
65 |
66 | ~~~cpp
67 | struct RPCClientParams param = RPC_CLIENT_PARAMS_DEFAULT;
68 | param.url = "srpc://127.0.0.1:1412";
69 | Example::SRPCClient client(¶m);
70 | ~~~
71 |
72 | 注意这里一定要使用`RPC_CLIENT_PARAMS_DEFAULT`去初始化我们的参数,里边包含了一个`RPCTaskParams`,包括默认的data_type、compress_type、重试次数和多种超时,具体结构可以参考[rpc_options.h](/src/rpc_options.h)。
73 |
74 |
--------------------------------------------------------------------------------
/src/compress/rpc_compress_snappy.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_COMPRESS_SNAPPY_H__
18 | #define __RPC_COMPRESS_SNAPPY_H__
19 |
20 | #include "rpc_buffer.h"
21 |
22 | namespace srpc
23 | {
24 |
25 | class SnappyManager
26 | {
27 | public:
28 | /*
29 | * compress serialized msg into buf.
30 | * ret: -1: failed
31 | * >0: byte count of compressed data
32 | */
33 | static int SnappyCompress(const char *msg, size_t msglen, char *buf, size_t buflen);
34 |
35 | /*
36 | * decompress and parse buf into msg
37 | * ret: -1: failed
38 | * >0: byte count of compressed data
39 | */
40 | static int SnappyDecompress(const char *buf, size_t buflen, char *msg, size_t msglen);
41 |
42 | /*
43 | * compress RPCBuffer src(Source) into RPCBuffer dst(Sink)
44 | * ret: -1: failed
45 | * >0: byte count of compressed data
46 | */
47 | static int SnappyCompressIOVec(RPCBuffer *src, RPCBuffer *dst);
48 |
49 | /*
50 | * decompress RPCBuffer src(Source) into RPCBuffer dst(Sink)
51 | * ret: -1: failed
52 | * >0: byte count of compressed data
53 | */
54 | static int SnappyDecompressIOVec(RPCBuffer *src, RPCBuffer *dst);
55 |
56 | /*
57 | * lease size after compress origin_size data
58 | */
59 | static int SnappyLeaseSize(size_t origin_size);
60 | };
61 |
62 | } // end namespace srpc
63 |
64 | #endif
65 |
66 |
--------------------------------------------------------------------------------
/tutorial/tutorial-14-trpc_http_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "workflow/WFFacilities.h"
19 | #include "helloworld.srpc.h"
20 | #include "srpc/rpc_types.h"
21 |
22 | using namespace srpc;
23 | using namespace trpc::test::helloworld;
24 |
25 | static WFFacilities::WaitGroup wait_group(1);
26 |
27 | int main()
28 | {
29 | Greeter::TRPCHttpClient client("127.0.0.1", 1412);
30 |
31 | //async
32 | HelloRequest req;
33 | req.set_msg("Hello, trpc-http server. This is srpc framework trpc-http client!");
34 |
35 | client.SayHello(&req, [](HelloReply *resp, RPCContext *ctx) {
36 | if (ctx->success())
37 | printf("%s\n", resp->DebugString().c_str());
38 | else
39 | printf("status[%d] error[%d] errmsg:%s\n",
40 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
41 | });
42 |
43 | //sync
44 | HelloRequest sync_req;
45 | HelloReply sync_resp;
46 | RPCSyncContext sync_ctx;
47 |
48 | sync_req.set_msg("Hi, trpc-http server. This is srpc framework trpc-http client!");
49 | client.SayHi(&sync_req, &sync_resp, &sync_ctx);
50 | if (sync_ctx.success)
51 | printf("%s\n", sync_resp.DebugString().c_str());
52 | else
53 | printf("status[%d] error[%d] errmsg:%s\n",
54 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
55 |
56 | wait_group.wait();
57 | return 0;
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/tutorial/tutorial-12-trpc_pb_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "workflow/WFFacilities.h"
19 | #include "helloworld.srpc.h"
20 | #include "srpc/rpc_types.h"
21 |
22 | using namespace srpc;
23 | using namespace trpc::test::helloworld;
24 |
25 | static WFFacilities::WaitGroup wait_group(1);
26 |
27 | int main()
28 | {
29 | Greeter::TRPCClient client("127.0.0.1", 1412);
30 |
31 | //async
32 | HelloRequest req;
33 | req.set_msg("Hello, trpc server. This is srpc framework trpc client!");
34 |
35 | client.SayHello(&req, [](HelloReply *resp, RPCContext *ctx) {
36 | if (ctx->success())
37 | printf("%s\n", resp->DebugString().c_str());
38 | else
39 | printf("status[%d] error[%d] errmsg:%s\n",
40 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
41 | wait_group.done();
42 | });
43 |
44 | //sync
45 | HelloRequest sync_req;
46 | HelloReply sync_resp;
47 | RPCSyncContext sync_ctx;
48 |
49 | sync_req.set_msg("Hi, trpc server. This is srpc framework trpc client!");
50 | client.SayHi(&sync_req, &sync_resp, &sync_ctx);
51 |
52 | if (sync_ctx.success)
53 | printf("%s\n", sync_resp.DebugString().c_str());
54 | else
55 | printf("status[%d] error[%d] errmsg:%s\n",
56 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
57 |
58 | wait_group.wait();
59 | return 0;
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/src/thrift/rpc_thrift_enum.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_THRIFT_ENUM_H__
18 | #define __RPC_THRIFT_ENUM_H__
19 |
20 | namespace srpc
21 | {
22 |
23 | static constexpr int THRIFT_STRUCT_FIELD_REQUIRED = 0;
24 | static constexpr int THRIFT_STRUCT_FIELD_OPTIONAL = 1;
25 | static constexpr int THRIFT_STRUCT_FIELD_DEFAULT = 2;
26 |
27 | enum ThriftMessageType
28 | {
29 | TMT_CALL = 1,
30 | TMT_REPLY = 2,
31 | TMT_EXCEPTION = 3,
32 | TMT_ONEWAY = 4
33 | };
34 |
35 | enum ThriftDataType
36 | {
37 | TDT_STOP = 0,
38 | TDT_VOID = 1,
39 | TDT_BOOL = 2,
40 | TDT_BYTE = 3,
41 | TDT_I08 = 3,
42 | TDT_I16 = 6,
43 | TDT_I32 = 8,
44 | TDT_U64 = 9,
45 | TDT_I64 = 10,
46 | TDT_DOUBLE = 4,
47 | TDT_STRING = 11,
48 | TDT_UTF7 = 11,
49 | TDT_STRUCT = 12,
50 | TDT_MAP = 13,
51 | TDT_SET = 14,
52 | TDT_LIST = 15,
53 | TDT_UTF8 = 16,
54 | TDT_UTF16 = 17
55 | };
56 |
57 | enum ThriftExceptionType
58 | {
59 | TET_UNKNOWN = 0,
60 | TET_UNKNOWN_METHOD = 1,
61 | TET_INVALID_MESSAGE_TYPE = 2,
62 | TET_WRONG_METHOD_NAME = 3,
63 | TET_BAD_SEQUENCE_ID = 4,
64 | TET_MISSING_RESULT = 5,
65 | TET_INTERNAL_ERROR = 6,
66 | TET_PROTOCOL_ERROR = 7,
67 | TET_INVALID_TRANSFORM = 8,
68 | TET_INVALID_PROTOCOL = 9,
69 | TET_UNSUPPORTED_CLIENT_TYPE = 10
70 | };
71 |
72 | } // end namespace srpc
73 |
74 | #endif
75 |
76 |
--------------------------------------------------------------------------------
/tutorial/tutorial-18-http_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2023 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "workflow/WFFacilities.h"
19 | #include "srpc/http_client.h"
20 | #include "srpc/rpc_types.h"
21 | #include "srpc/rpc_metrics_filter.h"
22 | #include "srpc/rpc_trace_filter.h"
23 |
24 | using namespace srpc;
25 |
26 | #define REDIRECT_MAX 5
27 | #define RETRY_MAX 2
28 |
29 | srpc::RPCTraceDefault trace_log;
30 | static WFFacilities::WaitGroup wait_group(1);
31 |
32 | void callback(WFHttpTask *task)
33 | {
34 | int state = task->get_state();
35 | int error = task->get_error();
36 | fprintf(stderr, "callback. state = %d error = %d\n", state, error);
37 |
38 | if (state == WFT_STATE_SUCCESS) // print server response body
39 | {
40 | const void *body;
41 | size_t body_len;
42 |
43 | task->get_resp()->get_parsed_body(&body, &body_len);
44 | fwrite(body, 1, body_len, stdout);
45 | fflush(stdout);
46 | fprintf(stderr, "\nfinish print body. body_len = %zu\n", body_len);
47 | }
48 |
49 | wait_group.done();
50 | }
51 |
52 | int main()
53 | {
54 | srpc::HttpClient client;
55 | client.add_filter(&trace_log);
56 |
57 | WFHttpTask *task = client.create_http_task("http://127.0.0.1:1412",
58 | REDIRECT_MAX,
59 | RETRY_MAX,
60 | callback);
61 | task->start();
62 | wait_group.wait();
63 |
64 | return 0;
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/GNUmakefile:
--------------------------------------------------------------------------------
1 | ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
2 | ALL_TARGETS := all base check install preinstall package rpm clean tutorial example
3 | MAKE_FILE := Makefile
4 |
5 | DEFAULT_BUILD_DIR := build.cmake
6 | BUILD_DIR := $(shell if [ -f $(MAKE_FILE) ]; then echo "."; else echo $(DEFAULT_BUILD_DIR); fi)
7 | CMAKE3 := $(shell if which cmake3>/dev/null ; then echo cmake3; else echo cmake; fi;)
8 | WORKFLOW := $(shell if [ -f "workflow/workflow-config.cmake.in" ]; then echo "Found"; else echo "NotFound"; fi)
9 |
10 | .PHONY: $(ALL_TARGETS)
11 |
12 | all: base
13 | make -C $(BUILD_DIR) -f Makefile
14 |
15 | base:
16 |
17 | ifeq ("$(WORKFLOW)","Found")
18 | make -C workflow
19 | endif
20 |
21 | mkdir -p $(BUILD_DIR)
22 |
23 | ifeq ($(DEBUG),y)
24 | cd $(BUILD_DIR) && $(CMAKE3) -D CMAKE_BUILD_TYPE=Debug $(ROOT_DIR)
25 | else ifneq ("${INSTALL_PREFIX}install_prefix", "install_prefix")
26 | cd $(BUILD_DIR) && $(CMAKE3) -DCMAKE_INSTALL_PREFIX:STRING=${INSTALL_PREFIX} $(ROOT_DIR)
27 | else
28 | cd $(BUILD_DIR) && $(CMAKE3) $(ROOT_DIR)
29 | endif
30 |
31 | tutorial: all
32 | make -C tutorial
33 |
34 | check: all
35 | make -C test check
36 |
37 | install preinstall package: base
38 | mkdir -p $(BUILD_DIR)
39 | cd $(BUILD_DIR) && $(CMAKE3) $(ROOT_DIR)
40 | make -C $(BUILD_DIR) -f Makefile $@
41 |
42 | rpm: package
43 | ifneq ($(BUILD_DIR),.)
44 | mv $(BUILD_DIR)/*.rpm ./
45 | endif
46 |
47 | clean:
48 | ifeq ("$(WORKFLOW)","Found")
49 | -make -C workflow clean
50 | endif
51 | -make -C test clean
52 | -make -C tutorial clean
53 | -make -C benchmark clean
54 | rm -rf $(DEFAULT_BUILD_DIR)
55 | rm -rf _include
56 | rm -rf _lib
57 | rm -rf _bin
58 | rm -f SRCINFO SRCNUMVER SRCVERSION
59 | rm -f ./*.rpm
60 | rm -f src/message/*.pb.h src/message/*.pb.cc
61 | find . -name CMakeCache.txt | xargs rm -f
62 | find . -name Makefile | xargs rm -f
63 | find . -name "*.cmake" | xargs rm -f
64 | find . -name CMakeFiles | xargs rm -rf
65 |
66 |
--------------------------------------------------------------------------------
/tutorial/tutorial-05-brpc_pb_server.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "echo_pb.srpc.h"
19 | #include "workflow/WFFacilities.h"
20 |
21 | using namespace srpc;
22 |
23 | static WFFacilities::WaitGroup wait_group(1);
24 |
25 | char attachment[10] = "ATTACH";
26 |
27 | class ExampleServiceImpl : public Example::Service
28 | {
29 | public:
30 | void Echo(EchoRequest *req, EchoResponse *resp, RPCContext *ctx) override
31 | {
32 | resp->set_message("Hi back, " + req->name());
33 | ctx->set_attachment_nocopy(attachment, strlen(attachment));
34 |
35 | printf("Server Echo()\nget_req:\n%s\nset_resp:\n%s\n",
36 | req->DebugString().c_str(), resp->DebugString().c_str());
37 | }
38 | };
39 |
40 | static void sig_handler(int signo)
41 | {
42 | wait_group.done();
43 | }
44 |
45 | int main()
46 | {
47 | GOOGLE_PROTOBUF_VERIFY_VERSION;
48 | signal(SIGINT, sig_handler);
49 | signal(SIGTERM, sig_handler);
50 |
51 | BRPCServer server;
52 | ExampleServiceImpl impl;
53 |
54 | server.add_service(&impl);
55 |
56 | if (server.start(1412) == 0)
57 | {
58 | printf("SRPC framework BRPC Protobuf server is running on 1412\n"
59 | "Try ./brpc_pb_client to send requests.\n\n");
60 | wait_group.wait();
61 | server.stop();
62 | }
63 | else
64 | perror("server start");
65 |
66 | google::protobuf::ShutdownProtobufLibrary();
67 | return 0;
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/tutorial/tutorial-06-brpc_pb_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "workflow/WFFacilities.h"
19 | #include "echo_pb.srpc.h"
20 |
21 | using namespace srpc;
22 |
23 | static WFFacilities::WaitGroup wait_group(1);
24 |
25 | int main()
26 | {
27 | Example::BRPCClient client("127.0.0.1", 1412);
28 |
29 | //async
30 | EchoRequest req;
31 | req.set_message("Hello, srpc!");
32 | req.set_name("1412");
33 |
34 | client.Echo(&req, [](EchoResponse *resp, RPCContext *ctx) {
35 | if (ctx->success())
36 | printf("%s\n", resp->DebugString().c_str());
37 | else
38 | printf("status[%d] error[%d] errmsg:%s\n",
39 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
40 |
41 | const char *attachment;
42 | size_t len;
43 |
44 | while (ctx->get_attachment(&attachment, &len))
45 | printf("get attachment [%.*s] len=%zu\n", (int)len, attachment, len);
46 |
47 | wait_group.done();
48 | });
49 |
50 | //sync
51 | EchoRequest sync_req;
52 | EchoResponse sync_resp;
53 | RPCSyncContext sync_ctx;
54 |
55 | sync_req.set_message("Hello, srpc!");
56 | sync_req.set_name("Sync");
57 |
58 | client.Echo(&sync_req, &sync_resp, &sync_ctx);
59 |
60 | if (sync_ctx.success)
61 | printf("%s\n", sync_resp.DebugString().c_str());
62 | else
63 | printf("status[%d] error[%d] errmsg:%s\n",
64 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
65 |
66 | wait_group.wait();
67 | return 0;
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/src/rpc_define.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_DEFINE_H__
18 | #define __RPC_DEFINE_H__
19 |
20 | #if __cplusplus < 201100
21 | #error CPLUSPLUS VERSION required at least C++11. Please use "-std=c++11".
22 | #include
23 | #endif
24 |
25 | #include "rpc_server.h"
26 | #include "rpc_client.h"
27 |
28 | namespace srpc
29 | {
30 |
31 | using SRPCServer = RPCServer;
32 | using SRPCClient = RPCClient;
33 | using SRPCClientTask = SRPCClient::TASK;
34 |
35 | using SRPCHttpServer = RPCServer;
36 | using SRPCHttpClient = RPCClient;
37 | using SRPCHttpClientTask = SRPCHttpClient::TASK;
38 |
39 | using BRPCServer = RPCServer;
40 | using BRPCClient = RPCClient;
41 | using BRPCClientTask = BRPCClient::TASK;
42 |
43 | using ThriftServer = RPCServer;
44 | using ThriftClient = RPCClient;
45 | using ThriftClientTask = ThriftClient::TASK;
46 |
47 | using ThriftHttpServer = RPCServer;
48 | using ThriftHttpClient = RPCClient;
49 | using ThriftHttpClientTask = ThriftHttpClient::TASK;
50 |
51 | using TRPCServer = RPCServer;
52 | using TRPCClient = RPCClient;
53 | using TRPCClientTask = TRPCClient::TASK;
54 |
55 | using TRPCHttpServer = RPCServer;
56 | using TRPCHttpClient = RPCClient;
57 | using TRPCHttpClientTask = TRPCHttpClient::TASK;
58 |
59 | } // namespace srpc
60 |
61 | #endif
62 |
63 |
--------------------------------------------------------------------------------
/srpc.bzl:
--------------------------------------------------------------------------------
1 | """
2 | Rules for building C++ srpc with Bazel.
3 | """
4 |
5 | load("@rules_cc//cc:defs.bzl", "cc_library")
6 |
7 | tool_path = ":srpc_generator"
8 |
9 | def srpc_cc_library(
10 | name,
11 | srcs,
12 | deps = [],
13 | type = "proto",
14 | out_prefix = "",
15 | visibility = None):
16 | output_directory = (
17 | ("$(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("$(@D)")
18 | )
19 |
20 | proto_output_headers = [
21 | (out_prefix + "%s.srpc.h") % (s.replace(".%s" % type, "").split("/")[-1])
22 | for s in srcs
23 | ]
24 | thrift_output_headers = [
25 | (out_prefix + "%s.thrift.h") % (s.replace(".%s" % type, "").split("/")[-1])
26 | for s in srcs
27 | ]
28 |
29 | if type == "thrift":
30 | output_headers = proto_output_headers + thrift_output_headers
31 | gen_proto = "thrift"
32 | if type == "proto":
33 | output_headers = proto_output_headers
34 | gen_proto = "protobuf"
35 |
36 | genrule_cmd = " ".join([
37 | "SRCS=($(SRCS));",
38 | "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
39 | "$(location %s)" % (tool_path),
40 | " %s " % gen_proto,
41 | "$$f",
42 | output_directory + ";",
43 | "done",
44 | ])
45 |
46 | srcs_lib = "%s_srcs" % (name)
47 |
48 | native.genrule(
49 | name = srcs_lib,
50 | srcs = srcs,
51 | outs = output_headers,
52 | tools = [tool_path],
53 | cmd = genrule_cmd,
54 | output_to_bindir = True,
55 | message = "Generating srpc files for %s:" % (name),
56 | )
57 |
58 | runtime_deps = deps + [":srpc"]
59 | print(runtime_deps)
60 |
61 | cc_library(
62 | name = name,
63 | hdrs = [
64 | ":" + srcs_lib,
65 | ],
66 | srcs = [
67 | ":" + srcs_lib,
68 | ],
69 | features = [
70 | "-parse_headers",
71 | ],
72 | deps = runtime_deps,
73 | includes = [],
74 | linkstatic = 1,
75 | visibility = visibility,
76 | )
77 |
--------------------------------------------------------------------------------
/src/rpc_basic.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2022 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 |
18 | #ifdef _WIN32
19 | #include
20 | #else
21 | #include
22 | #include
23 | #endif
24 | #include "rpc_basic.h"
25 | #include "rpc_module.h"
26 |
27 | namespace srpc
28 | {
29 |
30 | void RPCCommon::log_format(std::string& key, std::string& value,
31 | const RPCLogVector& fields)
32 | {
33 | if (fields.size() == 0)
34 | return;
35 |
36 | char buffer[100];
37 | snprintf(buffer, 100, "%s%c%lld", SRPC_SPAN_LOG, ' ', GET_CURRENT_MS());
38 | key = std::move(buffer);
39 | value = "{\"";
40 |
41 | for (auto& field : fields)
42 | {
43 | value = value + std::move(field.first) + "\":\""
44 | + std::move(field.second) + "\",";
45 | }
46 |
47 | value[value.length() - 1] = '}';
48 | }
49 |
50 | bool RPCCommon::addr_to_string(const struct sockaddr *addr,
51 | char *ip_str, socklen_t len,
52 | unsigned short *port)
53 | {
54 | const char *ret = NULL;
55 |
56 | if (addr->sa_family == AF_INET)
57 | {
58 | struct sockaddr_in *sin = (struct sockaddr_in *)addr;
59 |
60 | ret = inet_ntop(AF_INET, &sin->sin_addr, ip_str, len);
61 | *port = ntohs(sin->sin_port);
62 | }
63 | else if (addr->sa_family == AF_INET6)
64 | {
65 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
66 |
67 | ret = inet_ntop(AF_INET6, &sin6->sin6_addr, ip_str, len);
68 | *port = ntohs(sin6->sin6_port);
69 | }
70 | else
71 | errno = EINVAL;
72 |
73 | return ret != NULL;
74 | }
75 |
76 | } // namespace srpc
77 |
78 |
--------------------------------------------------------------------------------
/docs/docs-03-server.md:
--------------------------------------------------------------------------------
1 | [English version](/docs/en/docs-03-server.md)
2 |
3 | ## 03 - RPC Server
4 | - 每一个Server对应一个端口
5 | - 每一个Server对应一个确定的网络通信协议
6 | - 每一个Service可以添加到任意的Server里
7 | - 每一个Server可以拥有任意的Service,但在当前Server里ServiceName必须唯一
8 | - 不同IDL的Service是可以放进同一个Server中的
9 |
10 | ### 示例
11 | 下面我们通过一个具体例子来呈现
12 | - 沿用上面的``ExampleServiceImpl``Service
13 | - 首先,我们创建1个RPC Server、需要确定协议
14 | - 然后,我们可以创建任意个数的Service实例、任意不同proto形成的Service,把这些Service通过``add_service()``接口添加到Server里
15 | - 最后,通过Server的``start``或者``serve``开启服务,处理即将到来的rpc请求
16 | - 想像一下,我们也可以从``Example::Service``派生更多的功能的rpc``Echo``不同实现的Service
17 | - 想像一下,我们可以在N个不同的端口创建N个不同的RPC Server、代表着不同的协议
18 | - 想像一下,我们可以把同一个ServiceIMPL实例``add_service``到不同的Server上,我们也可以把不同的ServiceIMPL实例``add_service``到同一个Server上
19 | - 想像一下,我们可以用同一个``ExampleServiceImpl``,在三个不同端口、同时服务于BRPC-STD、SRPC-STD、SRPC-Http
20 | - 甚至,我们可以将1个PB的``ExampleServiceImpl``和1个Thrift的``AnotherThriftServiceImpl``,``add_service``到同一个SRPC-STD Server,两种IDL在同一个端口上完美工作!
21 |
22 | ~~~cpp
23 | int main()
24 | {
25 | SRPCServer server_srpc;
26 | SRPCHttpServer server_srpc_http;
27 | BRPCServer server_brpc;
28 | ThriftServer server_thrift;
29 | TRPCServer server_trpc;
30 | TRPCHttpServer server_trpc_http;
31 |
32 | ExampleServiceImpl impl_pb;
33 | AnotherThriftServiceImpl impl_thrift;
34 |
35 | server_srpc.add_service(&impl_pb);
36 | server_srpc.add_service(&impl_thrift);
37 | server_srpc_http.add_service(&impl_pb);
38 | server_srpc_http.add_service(&impl_thrift);
39 | server_brpc.add_service(&impl_pb);
40 | server_thrift.add_service(&impl_thrift);
41 | server_trpc.add_service(&impl_pb);
42 | server_trpc_http.add_service(&impl_thrift);
43 |
44 | server_srpc.start(1412);
45 | server_srpc_http.start(8811);
46 | server_brpc.start(2020);
47 | server_thrift.start(9090);
48 | server_trpc.start(2022);
49 | server_trpc_http.start(8822);
50 |
51 | getchar();
52 | server_trpc_http.stop();
53 | server_trpc.stop();
54 | server_thrift.stop();
55 | server_brpc.stop();
56 | server_srpc_http.stop();
57 | server_srpc.stop();
58 |
59 | return 0;
60 | }
61 | ~~~
62 |
63 |
--------------------------------------------------------------------------------
/tutorial/tutorial-17-http_server.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2023 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "workflow/WFFacilities.h"
19 | #include "srpc/http_server.h"
20 | #include "srpc/rpc_types.h"
21 | #include "srpc/rpc_metrics_filter.h"
22 | #include "srpc/rpc_trace_filter.h"
23 |
24 | static WFFacilities::WaitGroup wait_group(1);
25 |
26 | srpc::RPCMetricsPull exporter;
27 | srpc::RPCTraceDefault trace_log;
28 | //srpc::RPCTraceOpenTelemetry otel("http://127.0.0.1:4318");
29 |
30 | static void sig_handler(int signo)
31 | {
32 | wait_group.done();
33 | }
34 |
35 | void process(WFHttpTask *task)
36 | {
37 | fprintf(stderr, "http server get request_uri: %s\n",
38 | task->get_req()->get_request_uri());
39 |
40 | task->get_resp()->append_output_body("Hello from server!");
41 | }
42 |
43 | int main()
44 | {
45 | signal(SIGINT, sig_handler);
46 | signal(SIGTERM, sig_handler);
47 |
48 | srpc::HttpServer server(process);
49 |
50 | exporter.init(8080); /* export port for prometheus */
51 | exporter.create_histogram("echo_request_size", "Echo request size",
52 | {1, 10, 100});
53 | exporter.create_summary("echo_test_quantiles", "Test quantile",
54 | {{0.5, 0.05}, {0.9, 0.01}});
55 |
56 | server.add_filter(&trace_log);
57 | // server.add_filter(&otel);
58 | server.add_filter(&exporter);
59 |
60 | if (server.start(1412) == 0)
61 | {
62 | printf("HTTP protocol server is running on 1412\n"
63 | "Try ./http_client to send requests.\n\n");
64 | wait_group.wait();
65 | server.stop();
66 | }
67 | else
68 | perror("server start");
69 |
70 | exporter.deinit();
71 | return 0;
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/src/module/rpc_metrics_module.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2023 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include "rpc_metrics_module.h"
18 |
19 | namespace srpc
20 | {
21 |
22 | bool MetricsModule::client_begin(SubTask *task, RPCModuleData& data)
23 | {
24 | data[SRPC_START_TIMESTAMP] = std::to_string(GET_CURRENT_NS());
25 | // clear other unnecessary module_data since the data comes from series
26 | data.erase(SRPC_DURATION);
27 | data.erase(SRPC_FINISH_TIMESTAMP);
28 |
29 | return true;
30 | }
31 |
32 | bool MetricsModule::client_end(SubTask *task, RPCModuleData& data)
33 | {
34 | if (data.find(SRPC_START_TIMESTAMP) != data.end() &&
35 | data.find(SRPC_DURATION) == data.end())
36 | {
37 | unsigned long long end_time = GET_CURRENT_NS();
38 | data[SRPC_FINISH_TIMESTAMP] = std::to_string(end_time);
39 | data[SRPC_DURATION] = std::to_string(end_time -
40 | atoll(data[SRPC_START_TIMESTAMP].data()));
41 | }
42 |
43 | return true;
44 | }
45 |
46 | bool MetricsModule::server_begin(SubTask *task, RPCModuleData& data)
47 | {
48 | if (data.find(SRPC_START_TIMESTAMP) == data.end())
49 | data[SRPC_START_TIMESTAMP] = std::to_string(GET_CURRENT_NS());
50 |
51 | return true;
52 | }
53 |
54 | bool MetricsModule::server_end(SubTask *task, RPCModuleData& data)
55 | {
56 | if (data.find(SRPC_START_TIMESTAMP) != data.end() &&
57 | data.find(SRPC_DURATION) == data.end())
58 | {
59 | unsigned long long end_time = GET_CURRENT_NS();
60 |
61 | data[SRPC_FINISH_TIMESTAMP] = std::to_string(end_time);
62 | data[SRPC_DURATION] = std::to_string(end_time -
63 | atoll(data[SRPC_START_TIMESTAMP].data()));
64 | }
65 |
66 | return true;
67 | }
68 |
69 | } // end namespace srpc
70 |
71 |
--------------------------------------------------------------------------------
/tutorial/tutorial-09-client_task.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include
19 | #include "echo_pb.srpc.h"
20 | #include "workflow/WFFacilities.h"
21 |
22 | using namespace srpc;
23 |
24 | int main()
25 | {
26 | Example::SRPCClient client("127.0.0.1", 1412);
27 |
28 | EchoRequest req;
29 | req.set_message("Hello, srpc!");
30 | req.set_name("1412");
31 |
32 | auto *rpc_task = client.create_Echo_task([](EchoResponse *resp,
33 | RPCContext *ctx)
34 | {
35 | if (ctx->success())
36 | printf("%s\n", resp->DebugString().c_str());
37 | else
38 | printf("status[%d] error[%d] errmsg:%s\n",
39 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
40 | });
41 |
42 | auto *http_task = WFTaskFactory::create_http_task("https://www.sogou.com",
43 | 0, 0,
44 | [](WFHttpTask *task)
45 | {
46 | if (task->get_state() == WFT_STATE_SUCCESS)
47 | {
48 | std::string body;
49 | const void *data;
50 | size_t len;
51 |
52 | task->get_resp()->get_parsed_body(&data, &len);
53 | body.assign((const char *)data, len);
54 | printf("%s\n\n", body.c_str());
55 | }
56 | else
57 | printf("Http request fail\n\n");
58 | });
59 |
60 | rpc_task->serialize_input(&req);
61 | rpc_task->log({{"event", "info"}, {"message", "rpc client task log."}});
62 |
63 | WFFacilities::WaitGroup wait_group(1);
64 |
65 | SeriesWork *series = Workflow::create_series_work(http_task, [&wait_group](const SeriesWork *) {
66 | wait_group.done();
67 | });
68 | series->push_back(rpc_task);
69 | series->start();
70 |
71 | wait_group.wait();
72 | return 0;
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/tutorial/tutorial-04-srpc_thrift_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "workflow/WFFacilities.h"
19 | #include "echo_thrift.srpc.h"
20 |
21 | using namespace srpc;
22 |
23 | static WFFacilities::WaitGroup wait_group(1);
24 |
25 | int main()
26 | {
27 | Example::SRPCClient client("127.0.0.1", 1412);
28 |
29 | //sync
30 | EchoResult sync_res;
31 |
32 | client.Echo(sync_res, "Hello, srpc!", "1412");
33 |
34 | if (client.thrift_last_sync_success())
35 | printf("%s\n", sync_res.message.c_str());
36 | else
37 | {
38 | const auto& sync_ctx = client.thrift_last_sync_ctx();
39 |
40 | printf("status[%d] error[%d] errmsg:%s\n",
41 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
42 | }
43 |
44 | //async
45 | Example::EchoRequest req;
46 | req.message = "Hello, srpc!";
47 | req.name = "1412";
48 |
49 | client.Echo(&req, [](Example::EchoResponse *resp, RPCContext *ctx) {
50 | if (ctx->success())
51 | printf("%s\n", resp->result.message.c_str());
52 | else
53 | printf("status[%d] error[%d] errmsg:%s\n",
54 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
55 | wait_group.done();
56 | });
57 |
58 | //sync
59 | Example::EchoRequest sync_req;
60 | Example::EchoResponse sync_resp;
61 | RPCSyncContext sync_ctx;
62 |
63 | sync_req.message = "Hello, srpc!";
64 | sync_req.name = "Sync";
65 |
66 | client.Echo(&sync_req, &sync_resp, &sync_ctx);
67 |
68 | if (sync_ctx.success)
69 | printf("%s\n", sync_resp.result.message.c_str());
70 | else
71 | printf("status[%d] error[%d] errmsg:%s\n",
72 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
73 |
74 | wait_group.wait();
75 | return 0;
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/tutorial/tutorial-11-trpc_pb_server.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "helloworld.srpc.h"
19 | #include "workflow/WFFacilities.h"
20 | #include "srpc/rpc_types.h"
21 |
22 | using namespace srpc;
23 | using namespace trpc::test::helloworld;
24 |
25 | static WFFacilities::WaitGroup wait_group(1);
26 |
27 | class GreeterServiceImpl : public Greeter::Service
28 | {
29 | public:
30 | void SayHello(HelloRequest *req, HelloReply *resp, RPCContext *ctx) override
31 | {
32 | ctx->set_compress_type(RPCCompressGzip);
33 | resp->set_msg("This is SRPC framework TRPC protocol. Hello back.");
34 |
35 | printf("Server SayHello()\nget_req:\n%s\nset_resp:\n%s\n",
36 | req->DebugString().c_str(), resp->DebugString().c_str());
37 | }
38 |
39 | void SayHi(HelloRequest *req, HelloReply *resp, RPCContext *ctx) override
40 | {
41 | resp->set_msg("This is SRPC framework TRPC protocol. Hi back.");
42 |
43 | printf("Server SayHi()\nget_req:\n%s\nset_resp:\n%s\n",
44 | req->DebugString().c_str(), resp->DebugString().c_str());
45 | }
46 | };
47 |
48 | static void sig_handler(int signo)
49 | {
50 | wait_group.done();
51 | }
52 |
53 | int main()
54 | {
55 | GOOGLE_PROTOBUF_VERIFY_VERSION;
56 | signal(SIGINT, sig_handler);
57 | signal(SIGTERM, sig_handler);
58 |
59 | TRPCServer server;
60 | GreeterServiceImpl impl;
61 |
62 | server.add_service(&impl);
63 |
64 | if (server.start(1412) == 0)
65 | {
66 | printf("SRPC framework TRPC server is running on 1412\n"
67 | "Try ./trpc_pb_client to send requests.\n\n");
68 | wait_group.wait();
69 | server.stop();
70 | }
71 | else
72 | perror("server start");
73 |
74 | google::protobuf::ShutdownProtobufLibrary();
75 | return 0;
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/tutorial/tutorial-13-trpc_http_server.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2021 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "helloworld.srpc.h"
19 | #include "workflow/WFFacilities.h"
20 | #include "srpc/rpc_types.h"
21 |
22 | using namespace srpc;
23 | using namespace trpc::test::helloworld;
24 |
25 | static WFFacilities::WaitGroup wait_group(1);
26 |
27 | class GreeterServiceImpl : public Greeter::Service
28 | {
29 | public:
30 | void SayHello(HelloRequest *req, HelloReply *resp, RPCContext *ctx) override
31 | {
32 | ctx->set_compress_type(RPCCompressGzip);
33 | resp->set_msg("This is SRPC framework TRPC protocol. Hello back.");
34 |
35 | printf("Server SayHello()\nget_req:\n%s\nset_resp:\n%s\n",
36 | req->DebugString().c_str(), resp->DebugString().c_str());
37 | }
38 |
39 | void SayHi(HelloRequest *req, HelloReply *resp, RPCContext *ctx) override
40 | {
41 | resp->set_msg("This is SRPC framework TRPC protocol. Hi back.");
42 |
43 | printf("Server SayHi()\nget_req:\n%s\nset_resp:\n%s\n",
44 | req->DebugString().c_str(), resp->DebugString().c_str());
45 | }
46 | };
47 |
48 | static void sig_handler(int signo)
49 | {
50 | wait_group.done();
51 | }
52 |
53 | int main()
54 | {
55 | GOOGLE_PROTOBUF_VERIFY_VERSION;
56 | signal(SIGINT, sig_handler);
57 | signal(SIGTERM, sig_handler);
58 |
59 | TRPCHttpServer server;
60 | GreeterServiceImpl impl;
61 |
62 | server.add_service(&impl);
63 |
64 | if (server.start(1412) == 0)
65 | {
66 | printf("SRPC framework TRPCHttp server is running on 1412\n"
67 | "Try ./trpc_http_client to send requests.\n\n");
68 | wait_group.wait();
69 | server.stop();
70 | }
71 | else
72 | perror("server start");
73 |
74 | google::protobuf::ShutdownProtobufLibrary();
75 | return 0;
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/docs/docs-05-context.md:
--------------------------------------------------------------------------------
1 | [English version](/docs/en/docs-05-context.md)
2 |
3 | ## 05 - RPC Context
4 | - RPCContext专门用来辅助异步接口,Service和Client通用
5 | - 每一个异步接口都会提供Context,用来给用户提供更高级的功能,比如获取对方ip、获取连接seqid等
6 | - Context上一些功能是Server或Client独有的,比如Server可以设置回复数据的压缩方式,Client可以获取请求成功或失败
7 | - Context上可以通过get_series获得所在的series,与workflow的异步模式无缝结合
8 |
9 | ### RPCContext API - Common
10 | #### ``long long get_seqid() const;``
11 | 请求+回复视为1次完整通信,获得当前socket连接上的通信sequence id,seqid=0代表第1次
12 |
13 | #### ``std::string get_remote_ip() const;``
14 | 获得对方IP地址,支持ipv4/ipv6
15 |
16 | #### ``int get_peer_addr(struct sockaddr *addr, socklen_t *addrlen) const;``
17 | 获得对方地址,in/out参数为更底层的数据结构sockaddr
18 |
19 | #### ``const std::string& get_service_name() const;``
20 | 获取RPC Service Name
21 |
22 | #### ``const std::string& get_method_name() const;``
23 | 获取RPC Methode Name
24 |
25 | #### ``SeriesWork *get_series() const;``
26 | 获取当前ServerTask/ClientTask所在series
27 |
28 | ### RPCContext API - Only for client done
29 | #### ``bool success() const;``
30 | client专用。这次请求是否成功
31 |
32 | #### ``int get_status_code() const;``
33 | client专用。这次请求的rpc status code
34 |
35 | #### ``const char *get_errmsg() const;``
36 | client专用。这次请求的错误信息
37 |
38 | #### ``int get_error() const;``
39 | client专用。这次请求的错误码
40 |
41 | #### ``void *get_user_data() const;``
42 | client专用。获取ClientTask的user_data。如果用户通过create_xxx_task接口产生task,则可以通过user_data域记录上下文,在创建task时设置,在回调函数中拿回。
43 |
44 | ### RPCContext API - Only for server process
45 | #### ``void set_data_type(RPCDataType type);``
46 | Server专用。设置数据打包类型
47 | - RPCDataProtobuf
48 | - RPCDataThrift
49 | - RPCDataJson
50 |
51 | #### ``void set_compress_type(RPCCompressType type);``
52 | Server专用。设置数据压缩类型(注:Client的压缩类型在Client或Task上设置)
53 | - RPCCompressNone
54 | - RPCCompressSnappy
55 | - RPCCompressGzip
56 | - RPCCompressZlib
57 | - RPCCompressLz4
58 |
59 | #### ``void set_attachment_nocopy(const char *attachment, size_t len);``
60 | Server专用。设置attachment附件。
61 |
62 | #### ``bool get_attachment(const char **attachment, size_t *len) const;``
63 | Server专用。获取attachment附件。
64 |
65 | #### ``void set_reply_callback(std::function cb);``
66 | Server专用。设置reply callback,操作系统写入socket缓冲区成功后被调用。
67 |
68 | #### ``void set_send_timeout(int timeout);``
69 | Server专用。设置发送超时,单位毫秒。-1代表无限。
70 |
71 | #### ``void set_keep_alive(int timeout);``
72 | Server专用。设置连接保活时间,单位毫秒。-1代表无限。
73 |
74 |
--------------------------------------------------------------------------------
/src/rpc_options.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_OPTIONS_H__
18 | #define __RPC_OPTIONS_H__
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include "rpc_basic.h"
25 |
26 | namespace srpc {
27 |
28 | struct RPCTaskParams
29 | {
30 | int send_timeout;
31 | int receive_timeout;
32 | int watch_timeout;
33 | int keep_alive_timeout;
34 | int retry_max;
35 | int compress_type; //RPCCompressType
36 | int data_type; //RPCDataType
37 | };
38 |
39 | struct RPCClientParams
40 | {
41 | RPCTaskParams task_params;
42 | enum TransportType transport_type;
43 | //host + port + is_ssl
44 | std::string host;
45 | unsigned short port;
46 | bool is_ssl;
47 | //or URL
48 | std::string url;
49 | int callee_timeout;
50 | std::string caller;
51 | };
52 |
53 | struct RPCServerParams : public WFServerParams
54 | {
55 | RPCServerParams() : WFServerParams(SERVER_PARAMS_DEFAULT)
56 | {
57 | this->request_size_limit = RPC_BODY_SIZE_LIMIT;
58 | }
59 | };
60 |
61 | static constexpr struct RPCTaskParams RPC_TASK_PARAMS_DEFAULT =
62 | {
63 | /* .send_timeout = */ -1,
64 | /* .receive_timeout = */ -1,
65 | /* .watch_timeout = */ 0,
66 | /* .keep_alive_timeout = */ 30 * 1000,
67 | /* .retry_max = */ 0,
68 | /* .compress_type = */ RPCCompressNone,
69 | /* .data_type = */ RPCDataUndefined
70 | };
71 |
72 | static const struct RPCClientParams RPC_CLIENT_PARAMS_DEFAULT =
73 | {
74 | /* .task_params = */ RPC_TASK_PARAMS_DEFAULT,
75 | /* .transport_type = */ TT_TCP,
76 | /* .host = */ "",
77 | /* .port = */ SRPC_DEFAULT_PORT,
78 | /* .is_ssl = */ false,
79 | /* .url = */ "",
80 | /* .callee_timeout = */ -1,
81 | /* .caller = */ ""
82 | };
83 |
84 | static const RPCServerParams RPC_SERVER_PARAMS_DEFAULT;
85 |
86 | } // end namespace
87 |
88 | #endif
89 |
90 |
--------------------------------------------------------------------------------
/tools/templates/basic/compute_server_main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "workflow/WFHttpServer.h"
5 | #include "workflow/WFFacilities.h"
6 | #include "config/config.h"
7 |
8 | static WFFacilities::WaitGroup wait_group(1);
9 | static srpc::RPCConfig config;
10 |
11 | void sig_handler(int signo)
12 | {
13 | wait_group.done();
14 | }
15 |
16 | void init()
17 | {
18 | if (config.load("./server.conf") == false)
19 | {
20 | perror("Load config failed");
21 | exit(1);
22 | }
23 |
24 | signal(SIGINT, sig_handler);
25 | signal(SIGTERM, sig_handler);
26 | }
27 |
28 | // Example for Fibonacci.
29 | void Fibonacci(int n, protocol::HttpResponse *resp)
30 | {
31 | unsigned long long x = 0, y = 1;
32 | char buf[256];
33 | int i;
34 |
35 | if (n <= 0 || n > 94)
36 | {
37 | resp->append_output_body_nocopy("Invalid Number.",
38 | strlen("Invalid Number."));
39 | return;
40 | }
41 |
42 | resp->append_output_body_nocopy("", strlen(""));
43 | for (i = 2; i < n; i++)
44 | {
45 | sprintf(buf, "%llu + %llu = %llu.
", x, y, x + y);
46 | resp->append_output_body(buf);
47 | y = x + y;
48 | x = y - x;
49 | }
50 |
51 | if (n == 1)
52 | y = 0;
53 | sprintf(buf, "The No. %d Fibonacci number is: %llu.
", n, y);
54 | resp->append_output_body(buf);
55 | resp->append_output_body_nocopy("", strlen(""));
56 | }
57 |
58 | void process(WFHttpTask *task)
59 | {
60 | const char *uri = task->get_req()->get_request_uri();
61 | if (*uri == '/')
62 | uri++;
63 |
64 | int n = atoi(uri);
65 | protocol::HttpResponse *resp = task->get_resp();
66 | fprintf(stderr, "server get request. n = %d\n", n);
67 |
68 | // All calculations can be encapsulated by 'go_task'
69 | WFGoTask *go_task = WFTaskFactory::create_go_task("go", Fibonacci, n, resp);
70 |
71 | // Tasks will be dispatch asynchonously after 'push_back()'
72 | series_of(task)->push_back(go_task);
73 | }
74 |
75 | int main()
76 | {
77 | init();
78 |
79 | WFHttpServer server(process);
80 |
81 | if (server.start(config.server_port()) == 0)
82 | {
83 | fprintf(stderr, "Computing server started, port %u\n", config.server_port());
84 | wait_group.wait();
85 | server.stop();
86 | }
87 | else
88 | perror("server start");
89 |
90 | return 0;
91 | }
92 |
93 |
--------------------------------------------------------------------------------
/tutorial/tutorial-15-srpc_pb_proxy.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "echo_pb.srpc.h"
19 | #include "workflow/WFFacilities.h"
20 | #include "srpc/rpc_types.h"
21 |
22 | using namespace srpc;
23 |
24 | static WFFacilities::WaitGroup wait_group(1);
25 |
26 | template
27 | class ExampleProxyServiceImpl : public Example::Service
28 | {
29 | public:
30 | ExampleProxyServiceImpl(CLIENT *client)
31 | {
32 | this->client = client;
33 | }
34 |
35 | private:
36 | CLIENT *client;
37 |
38 | public:
39 | void Echo(EchoRequest *request, EchoResponse *response, RPCContext *context) override
40 | {
41 | printf("Proxy Server Echo() get and transfer request:\n%s\n",
42 | request->DebugString().c_str());
43 |
44 | auto *task = this->client->create_Echo_task([response](EchoResponse *resp,
45 | RPCContext *ctx) {
46 | printf("Proxy Server Echo() get and transfer response:\n%s\n",
47 | resp->DebugString().c_str());
48 | if (ctx->success())
49 | *response = std::move(*resp);
50 | });
51 | task->serialize_input(request);
52 | context->get_series()->push_back(task);
53 | }
54 | };
55 |
56 | static void sig_handler(int signo)
57 | {
58 | wait_group.done();
59 | }
60 |
61 | int main()
62 | {
63 | GOOGLE_PROTOBUF_VERIFY_VERSION;
64 | signal(SIGINT, sig_handler);
65 | signal(SIGTERM, sig_handler);
66 |
67 | SRPCServer server;
68 | Example::SRPCClient client("127.0.0.1", 1412);
69 | ExampleProxyServiceImpl impl(&client);
70 |
71 | server.add_service(&impl);
72 |
73 | if (server.start(61412) == 0)
74 | {
75 | printf("Proxy server serving on 61412 and redirect to backend server 127.0.0.1:1412\n"
76 | "Try start ./srpc_pb_server as backend and send requests to 61412.\n\n");
77 | wait_group.wait();
78 | server.stop();
79 | }
80 | else
81 | perror("server start");
82 |
83 | google::protobuf::ShutdownProtobufLibrary();
84 | return 0;
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci build
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 |
11 | ubuntu-cmake:
12 | name: ubuntu
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - uses: actions/checkout@master
17 | - name: install deps
18 | run: |
19 | sudo apt-get update
20 | sudo apt-get install -y libprotobuf-dev protobuf-compiler libgtest-dev valgrind
21 | - name: update submodules
22 | run: git submodule update --init --recursive
23 | - name: make
24 | run: make -j4
25 | - name: make tutorial
26 | run: make tutorial -j4
27 | - name: make check
28 | run: make check -j4
29 | - name: make install
30 | run: sudo make install
31 |
32 | fedora-cmake:
33 | name: fedora
34 | runs-on: ubuntu-latest
35 |
36 | steps:
37 | - name: Setup Podman
38 | run: |
39 | sudo apt update
40 | sudo apt-get -y install podman
41 | podman pull fedora:rawhide
42 | - name: Get source
43 | uses: actions/checkout@master
44 | with:
45 | path: 'workflow'
46 | - name: Create container and run tests
47 | run: |
48 | {
49 | echo 'FROM fedora:rawhide'
50 | echo 'RUN dnf -y update'
51 | echo 'RUN dnf -y install cmake gcc-c++ gtest-devel git make'
52 | echo 'RUN dnf -y install openssl-devel protobuf-devel'
53 | echo 'RUN dnf -y install lz4-devel snappy-devel'
54 | echo 'RUN dnf clean all'
55 | echo 'COPY workflow workflow'
56 | echo 'WORKDIR /workflow'
57 | echo 'RUN git submodule update --init --recursive'
58 | echo 'RUN cmake'
59 | echo 'RUN make'
60 | echo 'RUN make check'
61 | echo 'RUN make tutorial'
62 | } > podmanfile
63 | podman build --tag fedorarawhide -f ./podmanfile
64 |
65 | ubuntu-bazel:
66 | name: bazel
67 | runs-on: ubuntu-latest
68 |
69 | steps:
70 | - uses: actions/checkout@master
71 | - name: Install Bazel 5.4.0
72 | run: |
73 | sudo apt-get update
74 | sudo apt-get install -y apt-transport-https curl gnupg
75 | curl -LO "https://releases.bazel.build/5.4.0/release/bazel-5.4.0-linux-x86_64"
76 | chmod +x bazel-5.4.0-linux-x86_64
77 | sudo mv bazel-5.4.0-linux-x86_64 /usr/local/bin/bazel
78 | - name: bazel build
79 | run: bazel build ...
80 |
81 |
--------------------------------------------------------------------------------
/tutorial/tutorial-10-server_async.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include
19 | #include "echo_pb.srpc.h"
20 | #include "workflow/WFFacilities.h"
21 |
22 | using namespace srpc;
23 |
24 | static WFFacilities::WaitGroup wait_group(1);
25 |
26 | class ExampleServiceImpl : public Example::Service
27 | {
28 | public:
29 | void Echo(EchoRequest *req, EchoResponse *resp, RPCContext *ctx) override
30 | {
31 | ctx->set_compress_type(RPCCompressGzip);
32 | ctx->log({{"event", "info"}, {"message", "rpc server echo() end."}});
33 |
34 | auto *task = WFTaskFactory::create_http_task("https://www.sogou.com",
35 | 0, 0,
36 | [req, resp](WFHttpTask *task)
37 | {
38 | if (task->get_state() == WFT_STATE_SUCCESS)
39 | {
40 | const void *data;
41 | size_t len;
42 | task->get_resp()->get_parsed_body(&data, &len);
43 | resp->mutable_message()->assign((const char *)data, len);
44 | }
45 | else
46 | resp->set_message("Error: " + std::to_string(task->get_error()));
47 |
48 | printf("Server Echo()\nget_req:\n%s\nset_resp:\n%s\n",
49 | req->DebugString().c_str(), resp->DebugString().c_str());
50 | });
51 |
52 | ctx->get_series()->push_back(task);
53 | }
54 | };
55 |
56 | static void sig_handler(int signo)
57 | {
58 | wait_group.done();
59 | }
60 |
61 | int main(int argc, char *argv[])
62 | {
63 | GOOGLE_PROTOBUF_VERIFY_VERSION;
64 | signal(SIGINT, sig_handler);
65 | signal(SIGTERM, sig_handler);
66 |
67 | SRPCServer server;
68 | ExampleServiceImpl impl;
69 |
70 | server.add_service(&impl);
71 |
72 | if (server.start(1412) == 0)
73 | {
74 | printf("Asynchronous server with HTTP requests is running on 1412\n"
75 | "Try ./client_task or ./srpc_pb_client to trigger this example.\n\n");
76 | wait_group.wait();
77 | server.stop();
78 | }
79 | else
80 | perror("server start");
81 |
82 | google::protobuf::ShutdownProtobufLibrary();
83 | return 0;
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/tools/templates/proxy/proxy_main_proto.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "workflow/WFFacilities.h"
5 | #include "srpc/rpc_types.h"
6 |
7 | #include "config/config.h"
8 | #include "%s.srpc.h"
9 |
10 | using namespace srpc;
11 |
12 | static srpc::RPCConfig config;
13 | static WFFacilities::WaitGroup wait_group(1);
14 |
15 | static void sig_handler(int signo)
16 | {
17 | wait_group.done();
18 | }
19 |
20 | static void init()
21 | {
22 | if (config.load("./proxy.conf") == false)
23 | {
24 | perror("Load config failed");
25 | exit(1);
26 | }
27 |
28 | signal(SIGINT, sig_handler);
29 | signal(SIGTERM, sig_handler);
30 | }
31 |
32 | class ProxyServiceImpl : public %s::Service
33 | {
34 | public:
35 | void Echo(EchoRequest *request, EchoResponse *response,
36 | RPCContext *context) override
37 | {
38 | fprintf(stderr, "%s proxy get request from client. ip : %%s\n%%s\n",
39 | context->get_remote_ip().c_str(), request->DebugString().c_str());
40 |
41 | // 5. process() : get request from client and send to remote server
42 | auto *task = this->client.create_Echo_task([response](EchoResponse *resp,
43 | RPCContext *ctx) {
44 | // 6. callback() : fill remote server response to client
45 | if (ctx->success())
46 | *response = std::move(*resp);
47 | });
48 | task->serialize_input(request);
49 | context->get_series()->push_back(task);
50 | }
51 |
52 | public:
53 | ProxyServiceImpl(RPCClientParams *params) :
54 | client(params)
55 | {
56 | }
57 |
58 | private:
59 | %s::%sClient client;
60 | };
61 |
62 | int main()
63 | {
64 | // 1. load config
65 | init();
66 |
67 | // 2. make client for remote server
68 | RPCClientParams client_params = RPC_CLIENT_PARAMS_DEFAULT;
69 | client_params.host = config.client_host();
70 | client_params.port = config.client_port();
71 |
72 | // 3. start proxy server
73 | %sServer server;
74 | ProxyServiceImpl impl(&client_params);
75 | server.add_service(&impl);
76 | config.load_filter(server);
77 |
78 | if (server.start(config.server_port()) == 0)
79 | {
80 | // 4. main thread success and wait
81 | fprintf(stderr, "%s [%s]-[%s] proxy started, port %%u\n",
82 | config.server_port());
83 | wait_group.wait();
84 | server.stop();
85 | }
86 | else
87 | perror("server start");
88 |
89 | return 0;
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/tutorial/tutorial-08-thrift_thrift_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #include
18 | #include "echo_thrift.srpc.h"
19 |
20 | using namespace srpc;
21 |
22 | int main()
23 | {
24 | Example::ThriftClient client("127.0.0.1", 1412);
25 |
26 | //sync
27 | EchoResult sync_res;
28 |
29 | client.Echo(sync_res, "Hello, srpc!", "1412");
30 | if (client.thrift_last_sync_success())
31 | printf("%s\n", sync_res.message.c_str());
32 | else
33 | {
34 | const auto& sync_ctx = client.thrift_last_sync_ctx();
35 |
36 | printf("status[%d] error[%d] errmsg:%s\n",
37 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
38 | }
39 |
40 | //send/recv
41 | client.send_Echo("Hello, srpc!", "1412");
42 | //do anything you want
43 | client.recv_Echo(sync_res);
44 |
45 | if (client.thrift_last_sync_success())
46 | printf("%s\n", sync_res.message.c_str());
47 | else
48 | {
49 | const auto& sync_ctx = client.thrift_last_sync_ctx();
50 |
51 | printf("status[%d] error[%d] errmsg:%s\n",
52 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
53 | }
54 |
55 | //async
56 | Example::EchoRequest req;
57 | req.message = "Hello, srpc!";
58 | req.name = "1412";
59 |
60 | client.Echo(&req, [](Example::EchoResponse *resp, RPCContext *ctx) {
61 | if (ctx->success())
62 | printf("%s\n", resp->result.message.c_str());
63 | else
64 | printf("status[%d] error[%d] errmsg:%s\n",
65 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
66 | });
67 |
68 | //sync
69 | Example::EchoRequest sync_req;
70 | Example::EchoResponse sync_resp;
71 | RPCSyncContext sync_ctx;
72 |
73 | sync_req.message = "Hello, srpc!";
74 | sync_req.name = "Sync";
75 | client.Echo(&sync_req, &sync_resp, &sync_ctx);
76 |
77 | if (sync_ctx.success)
78 | printf("%s\n", sync_resp.result.message.c_str());
79 | else
80 | printf("status[%d] error[%d] errmsg:%s\n",
81 | sync_ctx.status_code, sync_ctx.error, sync_ctx.errmsg.c_str());
82 |
83 | return 0;
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/docs/en/docs-04-client.md:
--------------------------------------------------------------------------------
1 | [中文版](/docs/docs-04-client.md)
2 |
3 | ## 04 - RPC Client
4 |
5 | - Each Client corresponds to one specific target/one specific cluster
6 | - Each Client corresponds to one specific network communication protocol
7 | - Each Client corresponds to one specific IDL
8 |
9 | ### Sample
10 |
11 | You can follow the detailed example below:
12 |
13 | - Following the above example, the client is relatively simple and you can call the method directly.
14 | - Use `Example::XXXClient` to create a client instance of some RPC. The IP+port or URL of the target is required.
15 | - With the client instance, directly call the rpc function `Echo`. This is an asynchronous request, and the callback function will be invoked after the request is completed.
16 | - For the usage of the RPC Context, please check [RPC Context](/docs/en/rpc.md#rpc-context).
17 |
18 | ~~~cpp
19 | #include
20 | #include "example.srpc.h"
21 | #include "workflow/WFFacilities.h"
22 |
23 | using namespace srpc;
24 |
25 | int main()
26 | {
27 | Example::SRPCClient client("127.0.0.1", 1412);
28 | EchoRequest req;
29 | req.set_message("Hello!");
30 | req.set_name("SRPCClient");
31 |
32 | WFFacilities::WaitGroup wait_group(1);
33 |
34 | client.Echo(&req, [&wait_group](EchoResponse *response, RPCContext *ctx) {
35 | if (ctx->success())
36 | printf("%s\n", response->DebugString().c_str());
37 | else
38 | printf("status[%d] error[%d] errmsg:%s\n",
39 | ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
40 | wait_group.done();
41 | });
42 |
43 | wait_group.wait();
44 | return 0;
45 | }
46 | ~~~
47 |
48 | ### Client startup parameters
49 |
50 | Client can be started directly by passing in ip, port, or through client startup parameters.
51 |
52 | The above example:
53 |
54 | ~~~cpp
55 | Example::SRPCClient client("127.0.0.1", 1412);
56 | ~~~
57 |
58 | is equivalent to:
59 |
60 | ~~~cpp
61 | struct RPCClientParams param = RPC_CLIENT_PARAMS_DEFAULT;
62 | param.host = "127.0.0.1";
63 | param.port = 1412;
64 | Example::SRPCClient client(¶m);
65 | ~~~
66 |
67 | also equivalent to:
68 |
69 | ~~~cpp
70 | struct RPCClientParams param = RPC_CLIENT_PARAMS_DEFAULT;
71 | param.url = "srpc://127.0.0.1:1412";
72 | Example::SRPCClient client(¶m);
73 | ~~~
74 |
75 | Note that `RPC_CLIENT_PARAMS_DEFAULT` must be used to initialize the client's parameters, which contains a `RPCTaskParams`, including the default data_type, compress_type, retry_max and various timeouts. The specific struct can refer to [rpc_options.h](/src/rpc_options.h).
76 |
77 |
--------------------------------------------------------------------------------
/tools/templates/proxy/proxy_main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "workflow/WFTaskFactory.h"
4 | #include "workflow/WF%sServer.h"
5 | #include "workflow/WFFacilities.h"
6 |
7 | #include "config/config.h"
8 | #include "config/util.h"
9 |
10 | static WFFacilities::WaitGroup wait_group(1);
11 | static srpc::RPCConfig config;
12 |
13 | void sig_handler(int signo)
14 | {
15 | wait_group.done();
16 | }
17 |
18 | void init()
19 | {
20 | if (config.load("./proxy.conf") == false)
21 | {
22 | perror("Load config failed");
23 | exit(1);
24 | }
25 |
26 | signal(SIGINT, sig_handler);
27 | signal(SIGTERM, sig_handler);
28 | }
29 |
30 | void callback(WF%sTask *client_task)
31 | {
32 | int state = client_task->get_state();
33 | int error = client_task->get_error();
34 | SeriesWork *series = series_of(client_task);
35 | protocol::%sResponse *resp = client_task->get_resp();
36 | protocol::%sResponse *proxy_resp = (protocol::%sResponse *)series->get_context();
37 |
38 | // Copy the remote server's response, to proxy response.
39 | if (state == WFT_STATE_SUCCESS)%s
40 | fprintf(stderr, "backend server state = %%d error = %%d. response client.\n",
41 | state, error);
42 | }
43 |
44 | void process(WF%sTask *server_task)
45 | {
46 | protocol::%sRequest *req = server_task->get_req();
47 | std::string backend_server = config.client_host();
48 | unsigned short backend_server_port = config.client_port();
49 | std::string url = std::string("%s://") + backend_server +
50 | std::string(":") + std::to_string(backend_server_port);
51 |
52 | WF%sTask *client_task = WFTaskFactory::create_%s_task(url,%s
53 | config.retry_max(),
54 | callback);
55 |
56 | // Copy user's request to the new task's request using std::move()
57 | %s
58 | SeriesWork *series = series_of(server_task);
59 | series->set_context(server_task->get_resp());
60 | series->push_back(client_task);
61 |
62 | fprintf(stderr, "proxy get request from client: ");
63 | print_peer_address(server_task);
64 | }
65 |
66 | int main()
67 | {
68 | init();
69 |
70 | WF%sServer proxy_server(process);
71 |
72 | if (proxy_server.start(config.server_port()) == 0)
73 | {
74 | fprintf(stderr, "[%s]-[%s] proxy started, port %%u\n", config.server_port());
75 | wait_group.wait();
76 | proxy_server.stop();
77 | }
78 | else
79 | perror("server start");
80 |
81 | return 0;
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/src/generator/generator.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020 Sogou, Inc.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #ifndef __RPC_GENERATOR_H__
18 | #define __RPC_GENERATOR_H__
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include