### Start Development with Example Code Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md Instructions to set up a development environment by building from example code. This involves creating a build directory, configuring CMake, and building the project. It's a common pattern for starting development with CMake-based projects. ```shell mkdir build cd build cmake .. cmake --build . ``` -------------------------------- ### Coroutine RPC Server Setup and Handler Registration Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Demonstrates how to set up a corpc_server, register a coroutine-based handler function, and start the server. This is essential for enabling RPC communication using coroutines. ```cpp using namespace async_simple::coro; Lazy sleep(int seconds) { co_await coro_io::sleep(1s * seconds); // Yield the coroutine here co_return; } using namespace coro_rpc; void start() { coro_rpc_server server(/* thread = */1,/* port = */ 8801); server.register_handler(); server.start(); } ``` -------------------------------- ### Start coro_rpc Server (C++) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Demonstrates the basic procedure to start a coro_rpc server. It involves creating a `config_t` object, initializing a `coro_rpc_server` with the configuration, registering RPC functions (commented out), and then starting the server. Dependencies include `coro_rpc`. ```cpp int start() { coro_rpc::config_t config{}; coro_rpc_server server(config); /* Register rpc function here... */ server.start(); } ``` -------------------------------- ### Dynamic Reflection: Get/Set Field Values Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/struct_pb/struct_pb_intro.md Shows how to use dynamic reflection to retrieve field names, set field values by name (with type checking), and get field values by name and type. The example emphasizes that attempting to set a field with a non-matching type will result in an exception. Direct type specification for setting is also supported. ```cpp auto t = iguana::create_instance("nest1"); std::vector fields_name = t->get_fields_name(); CHECK(fields_name == std::vector{"name", "value", "var"}); my_struct mt{2, true, {42}}; t->set_field_value("value", mt); t->set_field_value("name", std::string("test")); t->set_field_value("var", 41); nest1 *st = dynamic_cast(t.get()); auto p = *st; std::cout << p.name << "\n"; auto &r0 = t->get_field_value("name"); CHECK(r0 == "test"); auto &r = t->get_field_value("var"); CHECK(r == 41); auto &r1 = t->get_field_value("value"); CHECK(r1.x == 2); ``` ```cpp t->set_field_value("name", "test"); ``` -------------------------------- ### Start coro_rpc Server (C++) Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md Initializes and starts a coro_rpc server. It takes the number of threads and the port as arguments, registers the 'echo' service handler, and then starts the server, blocking execution. This is a minimal server setup. ```cpp #include "rpc_service.hpp" #include int main() { coro_rpc_server server(/*thread_num =*/10, /*port =*/9000); server.register_handler(); // register function echo server.start(); // start the server & block } ``` -------------------------------- ### Coro_RPC Server Registration and Startup in C++ Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_client.md Demonstrates how to set up and start a Coro_RPC server. It initializes the server with a specific thread count and port, registers the `sleep` RPC handler, and then starts the server to listen for incoming requests. This code requires the `coro_rpc` library. ```cpp using namespace coro_rpc; void start() { coro_rpc_server server(/* thread = */1,/* port = */ 8801); server.register_handler(); server.start(); } ``` -------------------------------- ### coro_rpc Server Setup with RDMA Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_rdma.md Demonstrates how to initialize and start an RPC server using coro_rpc with RDMA communication enabled. It registers an echo handler and then initializes RDMA resources before starting the server. The default communication protocol is TCP; RDMA is enabled by calling init_ibv(). ```cpp std::string_view echo(std::string str) { return str; } coro_rpc_server server(/*thread_number*/ std::thread::hardware_concurrency(), /*port*/ 9000); server.register_handler(); server.init_ibv(); // Initialize RDMA resources server.start(); ``` -------------------------------- ### Dynamic Reflection: Create Instance Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/struct_pb/struct_pb_intro.md Illustrates how to create instances of structs dynamically using their name as a string. This requires the struct to inherit from `struct_pb::base_impl` (or `iguana::base_imple` in this example). An exception is thrown if the struct does not meet this inheritance requirement. ```cpp struct my_struct { int x; bool y; iguana::fixed64_t z; }; YLT_REFL(my_struct, x, y, z); struct nest1 : public iguana::base_imple { nest1() = default; nest1(std::string s, my_struct t, int d) : name(std::move(s)), value(t), var(d) {} std::string name; my_struct value; int var; }; YLT_REFL(nest1, name, value, var); ``` ```cpp std::shared_ptr t = struct_pb::create_instance("nest1"); ``` -------------------------------- ### CMake: Configure Build for YalantingLibs Examples Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_http/examples/CMakeLists.txt This snippet configures the CMake build environment for YalantingLibs examples. It sets the runtime output directory for examples and handles cases where yalantinglibs is either built from source or found as an installed package. It specifies C++20 standard and includes necessary libraries like Threads and yalantinglibs. ```cmake if("${yaLanTingLibs_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/examples/coro_http) else() # else find installed yalantinglibs cmake_minimum_required(VERSION 3.15) project(file_transfer) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Threads REQUIRED) link_libraries(Threads::Threads) # if you have install ylt find_package(yalantinglibs REQUIRED) link_libraries(yalantinglibs::yalantinglibs) # else # include_directories(include) # include_directories(include/ylt/thirdparty) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines") #-ftree-slp-vectorize with coroutine cause link error. disable it util gcc fix. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-tree-slp-vectorize") endif() endif() ``` -------------------------------- ### Coro_RPC Server-Side Benchmark Command Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_client.md Example command to start the Coro_RPC benchmark server. It specifies the server port, response data length, and log level. The server will listen on port 9004, send responses of 13 bytes, and use an error log level (5). ```bash ./bench -p 9004 -r 13 -o 5 ``` -------------------------------- ### CMake Build Configuration for Coro RPC RDMA Example Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_rpc/examples/rdma_example/CMakeLists.txt This snippet outlines the CMake commands used to configure the build for the `coro_rpc_rdma_example`. It sets the runtime output directory for executables and links the necessary `libverbs` library for RDMA functionality. ```cmake set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/examples/coro_rpc) add_executable(coro_rpc_rdma_example rdma_example.cpp ) target_link_libraries(coro_rpc_rdma_example -libverbs) ``` -------------------------------- ### CMake: Build RPC Example with Msgpack Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/CMakeLists.txt This CMake snippet builds an executable for an RPC example that uses the REST RPC protocol and Msgpack. It compiles `server/main.cpp` and `server/rpc_service.cpp`, defines preprocessor macros for Msgpack support, and links necessary Windows network libraries when using MinGW. ```cmake find_package(Msgpack) if (Msgpack_FOUND) add_executable(coro_rpc_example_use_rest_rpc_protocol server/main.cpp server/rpc_service.cpp ) target_compile_definitions(coro_rpc_example_use_rest_rpc_protocol PRIVATE HAVE_MSGPACK) target_compile_definitions(coro_rpc_example_use_rest_rpc_protocol PRIVATE MSGPACK_NO_BOOST) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows") # mingw-w64 target_link_libraries(coro_rpc_example_use_rest_rpc_protocol wsock32 ws2_32) endif() else() message(WARNING "Could Not Found Msgpack, disable coro_rpc_example_use_rest_rpc_protocol") endif() ``` -------------------------------- ### Example Ordinary RPC Functions Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Demonstrates the definition of ordinary RPC functions suitable for registration with coro_rpc. These functions are neither coroutines nor do they accept a `coro_rpc::context` as their first parameter. Examples include simple arithmetic and string manipulation functions. ```cpp int add(int a, int b); std::string_view echo(std::string_view str); struct dummy { std::string_view echo(std::string_view str) { return str; } }; ``` -------------------------------- ### Coro_RPC Benchmark Result Example Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_client.md An example output from a Coro_RPC performance test, showing average queries per second (QPS), throughput in Gb/s, and latency statistics (median, 90th, 95th, 99th percentiles) in microseconds. This data helps in evaluating the performance of the RPC framework under specific test conditions. ```text # Benchmark result avg qps 2757 and throughput:185.04 Gb/s in duration 30 # HELP Latency(us) of rpc call help # TYPE Latency(us) of rpc call summary rpc call latency(us){quantile="0.500000"} 3616.000000 rpc call latency(us){quantile="0.900000"} 3712.000000 rpc call latency(us){quantile="0.950000"} 3776.000000 rpc call latency(us){quantile="0.990000"} 3872.000000 rpc call latency(us)_sum 298707968.000000 rpc call latency(us)_count 82761 ``` -------------------------------- ### Configure coro_rpc Server for RDMA Support Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Shows a C++ example of initializing the coro_rpc server with RDMA support. This configuration is done by calling `init_ibv` with appropriate configuration options, enabling high-performance, low-latency communication. ```cpp coro_rpc_server server; server.init_ibv(ib_socket_t::config_t{}); ``` -------------------------------- ### C++ CoroHTTP Server and Client Basic Usage Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md Demonstrates the basic usage of the CoroHTTP library for C++20, including setting up a simple HTTP server with GET handlers and making asynchronous GET and POST requests using the client. It requires including coro_http_server.hpp and coro_http_client.hpp. The example shows server start-up, request handling, and client response assertion. ```cpp #include "ylt/coro_http/coro_http_server.hpp" #include "ylt/coro_http/coro_http_client.hpp" using namespace coro_http; async_simple::coro::Lazy basic_usage() { coro_http_server server(1, 9001); server.set_http_handler( "/get", [](coro_http_request &req, coro_http_response &resp) { resp.set_status_and_content(status_type::ok, "ok"); }); server.set_http_handler( "/coro", [](coro_http_request &req, coro_http_response &resp) -> async_simple::coro::Lazy { resp.set_status_and_content(status_type::ok, "ok"); co_return; }); server.aync_start(); // aync_start() don't block, sync_start() will block. std::this_thread::sleep_for(300ms); // wait for server start coro_http_client client{}; auto result = co_await client.async_get("http://127.0.0.1:9001/get"); assert(result.status == 200); assert(result.resp_body == "ok"); for (auto [key, val] : result.resp_headers) { std::cout << key << ": " << val << "\n"; } } async_simple::coro::Lazy get_post(coro_http_client &client) { std::string uri = "http://www.example.com"; auto result = co_await client.async_get(uri); std::cout << result.status << "\n"; result = co_await client.async_post(uri, "hello", req_content_type::string); std::cout << result.status << "\n"; } int main() { coro_http_client client{}; async_simple::coro::syncAwait(get_post(client)); } ``` -------------------------------- ### Install yalantinglibs using CMake Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md Install the yalantinglibs library after it has been built. This command installs the library to the default installation path or a user-defined path if specified with the '--prefix' option. ```shell cmake --install . # --prefix ./user_defined_install_path ``` -------------------------------- ### Install yaLanTingLibs using Vcpkg Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md This snippet demonstrates installing yaLanTingLibs via Vcpkg and integrating it into a CMake project. Make sure Vcpkg is set up correctly before proceeding. ```shell # Install Vcpkg first if you don't have it ./vcpkg install yalantinglibs ``` ```cmake find_package(yalantinglibs CONFIG REQUIRED) target_link_libraries(main PRIVATE yalantinglibs::yalantinglibs) ``` -------------------------------- ### Initialize Git Repository Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/guide/how_to_use_as_git_submodule.md Initializes a new Git repository in the current directory. This command sets up the necessary `.git` directory to start version control for your project. ```bash git init ``` -------------------------------- ### Install yaLanTingLibs using Homebrew Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md This snippet shows how to install yaLanTingLibs using the Homebrew package manager and how to link it in a CMake project. Ensure Homebrew is installed before running the commands. ```shell # Install Homebrew first if you don't have it brew install yalantinglibs ``` ```cmake find_package(yalantinglibs CONFIG REQUIRED) target_link_libraries(main PRIVATE yalantinglibs::yalantinglibs) ``` -------------------------------- ### Install yaLanTingLibs Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/guide/how_to_use_by_cmake_find_package.md Installs the yaLanTingLibs library after it has been built. The `make install` command typically copies the library files and headers to standard system locations, potentially requiring elevated privileges. ```shell # sudo if needed make install ``` -------------------------------- ### CMakeLists.txt Example for yaLanTingLibs Integration Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/guide/how_to_use_by_cmake_find_package.md An example CMakeLists.txt file demonstrating how to configure a project to use yaLanTingLibs. It sets C++ standard, finds required packages like Threads and yaLanTingLibs, and links them to an executable target. ```cmake cmake_minimum_required(VERSION 3.15) project(file_transfer) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Threads REQUIRED) link_libraries(Threads::Threads) find_package(yalantinglibs REQUIRED) link_libraries(yalantinglibs::yalantinglibs) add_executable(coro_io_example main.cpp) ``` -------------------------------- ### Calling Member Functions via RPC (Client-Side) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Shows how to invoke registered member functions on the client-side using coro_rpc. This example demonstrates calling regular, coroutine, and callback-based member functions remotely. ```cpp #include "rpc_service.h" #include Lazy test_client() { coro_rpc_client client; co_await client.connect("localhost", /*port =*/"9000"); // calling RPC { auto result = co_await client.call<&dummy::echo>("hello"); assert(result.value() == "hello"); } { auto result = co_await client.call<&dummy::coroutine_echo>("hello"); assert(result.value() == "hello"); } { auto result = co_await client.call<&dummy::callback_echo>("hello"); assert(result.value() == "hello"); } } ``` -------------------------------- ### Serialization and Deserialization with struct_pb Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/struct_pb/struct_pb_intro.md Demonstrates the core serialization and deserialization functionality of struct_pb. The `to_pb` function serializes a struct instance into a string, and `from_pb` deserializes it back into another instance. Assertions verify data integrity after the round trip. ```cpp int main() { nest v{"Hi", {1, false, {3}}, 5}, v2{}; std::string s; struct_pb::to_pb(v, s); struct_pb::from_pb(v2, s); assert(v.var == v2.var); assert(v.value.y == v2.value.y); assert(v.value.z == v2.value.z); } ``` -------------------------------- ### CMake: Define Executables for RPC Examples Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_rpc/examples/base_examples/CMakeLists.txt This CMake snippet defines several executable targets for various RPC examples, including load balancer, client pools, and a basic server. Each executable is built from its respective source file(s). ```cmake add_executable(coro_rpc_example_load_balancer load_balancer.cpp) add_executable(coro_rpc_example_client_pool client_pool.cpp) add_executable(coro_rpc_example_client_pools client_pools.cpp) add_executable(coro_rpc_example_client client.cpp) add_executable(coro_rpc_example_concurrent_clients concurrent_clients.cpp) add_executable(coro_rpc_example_server server.cpp rpc_service.cpp) ``` -------------------------------- ### CMake: Define Executable Targets for Examples Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_http/examples/CMakeLists.txt This CMake snippet defines the executable targets for various examples within the YalantingLibs project. It includes 'coro_http_example', 'coro_http_load_balancer', and 'coro_chat_room'. It also conditionally adds 'ntls_http_server' and 'ntls_http_client' if the YLT_ENABLE_NTLS option is set. ```cmake add_executable(coro_http_example example.cpp) add_executable(coro_http_load_balancer load_balancer.cpp) add_executable(coro_chat_room chat_room.cpp) if(YLT_ENABLE_NTLS) message(STATUS "Building NTLS examples with Tongsuo support") add_executable(ntls_http_server ntls_http_server.cpp) add_executable(ntls_http_client ntls_http_client.cpp) target_compile_definitions(ntls_http_server PRIVATE YLT_ENABLE_NTLS) target_compile_definitions(ntls_http_client PRIVATE YLT_ENABLE_NTLS) endif() ``` -------------------------------- ### Calling Specialized Template Functions via RPC (Client-Side) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Shows how to call specialized template functions on the client-side using coro_rpc. This example demonstrates calling remote template functions with different data types. ```cpp using namespace coro_rpc; using namespace async_simple::coro; Lazy rpc_call(coro_rpc_client& cli) { assert(co_await cli.call>(42).value() == 42); assert(co_await cli.call>("Hello").value() == "Hello"); assert(co_await cli.call>>(std::vector{1,2,3}).value() == std::vector{1,2,3}); } ``` -------------------------------- ### Start Asynchronous coro_rpc Server Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Starts the coro_rpc server asynchronously without blocking the current thread. It returns a future object that can be used to check the server's status and wait for its termination. The server is guaranteed to be listening after the function returns, or an error will be indicated. ```cpp int start_server() { coro_rpc_server server; regist_rpc_funtion(server); async_simple::Future ec = server.async_start(); /*won't block here */ assert(!ec.hasResult()) /* check if server start success */ auto err = ec.get(); /*block here util server down then return err code*/ } ``` -------------------------------- ### Manually Install and Build yaLanTingLibs Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md This section outlines the steps for manually cloning the yaLanTingLibs repository, building it using CMake, and running tests. This is useful if you prefer to manage dependencies directly or build from source. ```shell git clone https://github.com/alibaba/yalantinglibs.git cd yalantinglibs mkdir build cd build cmake .. cmake --build . --config debug # add -j, if you have enough memory to parallel compile ctest . ``` -------------------------------- ### CMake: Conditional Build Configuration Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_io/examples/CMakeLists.txt Configures the runtime output directory for examples based on whether the source directory is the same as the CMAKE_SOURCE_DIR. This allows for different build behaviors when running examples directly from the source versus from an installed version. ```cmake if("${yaLanTingLibs_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/examples) else() # else find installed yalantinglibs cmake_minimum_required(VERSION 3.15) project(file_transfer) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Threads REQUIRED) link_libraries(Threads::Threads) # if you have install ylt find_package(yalantinglibs REQUIRED) link_libraries(yalantinglibs::yalantinglibs) # else # include_directories(include) # include_directories(include/ylt/thirdparty) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines") #-ftree-slp-vectorize with coroutine cause link error. disable it util gcc fix. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-tree-slp-vectorize") endif() endif() ``` -------------------------------- ### Easylog: Initialize and Use Basic Logging Source: https://context7.com/alibaba/yalantinglibs/llms.txt Demonstrates the initialization and basic usage of the easylog asynchronous logging library. It covers setting severity levels, log file paths, and output options. Requires the easylog library. ```cpp #include int main() { // Initialize logging easylog::init_log( easylog::Severity::DEBUG, // Minimum log level "app.log", // Log file path true, // Async mode true, // Also output to console 10 * 1024 * 1024, // Max 10MB per file 5, // Keep 5 files true // Flush every time ); // Basic logging ELOG_INFO << "Application started"; ELOG_DEBUG << "Debug information: " << 42; ELOG_WARN << "Warning message"; ELOG_ERROR << "Error occurred: " << "file not found"; // Short macros ELOGI << "Info message"; ELOGD << "Debug message"; ELOGW << "Warning"; ELOGE << "Error"; // Printf-style logging int count = 10; std::string user = "Alice"; ELOGV(INFO, "User %s logged in, attempt %d", user.c_str(), count); // Format-style (requires fmt library) ELOGFMT(INFO, "Processing {} items at {}", count, "12:00"); return 0; } ``` -------------------------------- ### CMake: Configure Subproject or Find Installed Yalantinglibs Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/CMakeLists.txt This snippet determines if the current CMake build is a subproject of yalantinglibs or if it should find an installed version. It sets up the C++ standard, includes necessary libraries like Threads and yalantinglibs, and conditionally enables specific compiler flags for coroutines on GNU compilers. ```cmake if("${yaLanTingLibs_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") # if is the subproject of yalantinglibs # do nothing else() # else find installed yalantinglibs cmake_minimum_required(VERSION 3.15) project(file_transfer) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Threads REQUIRED) link_libraries(Threads::Threads) # if you have install ylt find_package(yalantinglibs REQUIRED) link_libraries(yalantinglibs::yalantinglibs) # else # include_directories(include) # include_directories(include/ylt/thirdparty) # When using coro_rpc_client to send request, only remote function declarations are required. # In the examples, RPC function declaration and definition are divided. # However, clang + ld(gold linker) + '-g' will report 'undefined reference to xxx'. # So you can use lld when compiler is clang by this code: # if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # add_link_options(-fuse-ld=lld) # endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines") #-ftree-slp-vectorize with coroutine cause link error. disable it util gcc fix. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-tree-slp-vectorize") endif() endif() ``` -------------------------------- ### Manual Build and Test for yalantinglibs Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/guide/what_is_yalantinglibs.md This shell script outlines the steps for manually building and testing the yalantinglibs project after cloning the repository. It involves creating a build directory, configuring the build with CMake, compiling the project (optionally in parallel), and running tests. The output executables (test/example/benchmark) will be located in the `./build/output/` directory. ```shell git clone https://github.com/alibaba/yalantinglibs.git cd yalantinglibs mkdir build cd build cmake .. cmake --build . --config debug # add -j, if you have enough memory to parallel compile ctest . # run tests ``` -------------------------------- ### CMake Conditional Logic for YalantingLibs Build Source: https://github.com/alibaba/yalantinglibs/blob/main/src/struct_yaml/examples/CMakeLists.txt This CMake script dynamically configures the build based on whether it's a subproject within yalantinglibs or uses an installed version. It sets output directories and finds the necessary library. ```cmake if("${yaLanTingLibs_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") # If this is a subproject in ylt set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/examples) else() # else find installed yalantinglibs cmake_minimum_required(VERSION 3.15) project(coro_rpc_examples) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) # if you have install ylt find_package(yalantinglibs REQUIRED) link_libraries(yalantinglibs::yalantinglibs) # else # include_directories(include) # include_directories(include/ylt/thirdparty) endif() add_executable(struct_yaml_example main.cpp ) ``` -------------------------------- ### Configure coro_rpc Server for SSL Support Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Provides a C++ code snippet demonstrating how to initialize the coro_rpc server with SSL support using OpenSSL. This involves specifying the base path for SSL files and the paths to the certificate and key files. ```cpp coro_rpc_server server; server.init_ssl({ .base_path = "./", // Base path of ssl files. .cert_file = "server.crt", // Path of the certificate relative to base_path. .key_file = "server.key" // Path of the private key relative to base_path. }); ``` -------------------------------- ### Create and Configure Custom RDMA Device Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_client.md Demonstrates creating a custom `ib_device_t` instance, allowing manual specification of device name, port, GID index, and buffer pool configuration. If `dev_name` is empty, the first available device is used. ```cpp auto dev = coro_io::ib_device_t::create({ .dev_name = "", // If dev_name is empty, the first device in the device list will be used. .port = 1, // Manually specify the NIC port number. .use_best_gid_index = true, // Automatically find the best GID index for this device. .gid_index = 0, // Manually specify the GID index; takes effect when automatic lookup is disabled or fails. .buffer_pool_config = { // ... } }); ``` -------------------------------- ### CMake: Configure Yalantinglibs Build Source: https://github.com/alibaba/yalantinglibs/blob/main/src/struct_pb/examples/CMakeLists.txt This CMake script configures the build environment for Yalantinglibs. It sets the runtime output directory for examples when building as a subproject and includes logic to find and link the installed yalantinglibs package when building as a standalone project. It also sets C++ standard to 17 and ensures the build type is Release if not specified. ```cmake if("${yaLanTingLibs_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") # If this is a subproject in ylt set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/examples) else() # else find installed yalantinglibs cmake_minimum_required(VERSION 3.15) project(struct_pb_examples) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) # if you have install ylt find_package(yalantinglibs REQUIRED) link_libraries(yalantinglibs::yalantinglibs) # else # include_directories(include) # include_directories(include/ylt/thirdparty) endif() add_executable(struct_pb_examples main.cpp ) ``` -------------------------------- ### Complete RPC Application with Server and Client Source: https://context7.com/alibaba/yalantinglibs/llms.txt A full example of an RPC application including a server and a client. It demonstrates defining custom data types, handling RPC calls on the server-side, and making calls from the client with custom types and error handling. ```cpp // common.hpp - Shared definitions #pragma once #include #include struct user { int64_t id; std::string username; std::string email; int age; }; struct query_result { bool success; std::string message; std::vector users; }; // Server-side functions inline user get_user(int64_t id) { return user{id, "user" + std::to_string(id), "user@example.com", 25}; } inline query_result query_users(int min_age, int max_age) { query_result result; result.success = true; result.message = "Query successful"; for (int i = 0; i < 3; i++) { result.users.push_back(user{i, "user" + std::to_string(i), "user" + std::to_string(i) + "@example.com", min_age + i}); } return result; } ``` ```cpp // server.cpp #include "common.hpp" #include #include int main() { easylog::init_log(easylog::Severity::INFO, "server.log", true, true); coro_rpc::coro_rpc_server server(4, 9000); // Register handlers server.register_handler(); ELOGI << "RPC Server starting on port 9000"; server.start(); // Blocking return 0; } ``` ```cpp // client.cpp #include "common.hpp" #include #include #include using namespace coro_rpc; using namespace async_simple::coro; Lazy test_rpc() { coro_rpc_client client; // Connect auto err = co_await client.connect("localhost", "9000"); if (err) { std::cerr << "Connection failed: " << err.message() << "\n"; co_return; } std::cout << "Connected to server\n"; // Get single user auto user_result = co_await client.call(123); if (!user_result) { std::cerr << "RPC error: " << user_result.error().msg << "\n"; co_return; } const auto& u = user_result.value(); std::cout << "User: " << u.username << " (" << u.email << "), age " << u.age << "\n"; // Query multiple users auto query = co_await client.call(20, 40); if (query && query.value().success) { std::cout << query.value().message << "\n"; std::cout << "Found " << query.value().users.size() << " users:\n"; for (const auto& user : query.value().users) { std::cout << " - " << user.username << ", age " << user.age << "\n"; } } std::cout << "RPC test completed\n"; } int main() { syncAwait(test_rpc()); return 0; } ``` -------------------------------- ### RPC ABI Compatibility with struct_pack (Server-Side) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Demonstrates server-side implementation for maintaining RPC ABI compatibility. It shows how to define functions that accept or return compatible types, allowing older clients to interact with newer servers by providing default values for missing compatible fields. ```cpp int client_oldapi_server_newapi(int a, struct_pack::compatible b) { return a + b.value_or(1); } int client_newapi_server_oldapi(int a) { return a; } std::tuple> client_oldapi_server_newapi_ret() { return {42,1}; } int client_newapi_server_oldapi_ret() { return 42; } std::tuple> client_oldapi_server_newapi_ret_void() { return {std::monostate{},1}; } void client_newapi_server_oldapi_ret_void() { return; } ``` -------------------------------- ### CMake: Windows-Specific Linking for Examples Source: https://github.com/alibaba/yalantinglibs/blob/main/src/coro_http/examples/CMakeLists.txt This CMake code handles platform-specific linking requirements for Windows, specifically for MinGW-w64 compiler. It links 'ws2_32' and 'mswsock' libraries to the example executables ('coro_http_example', 'coro_http_load_balancer', 'coro_chat_room') and also to the NTLS examples if they are enabled. ```cmake if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows") # mingw-w64 target_link_libraries(coro_http_example PRIVATE ws2_32 mswsock) target_link_libraries(coro_http_load_balancer PRIVATE ws2_32 mswsock) target_link_libraries(coro_chat_room PRIVATE ws2_32 mswsock) if(YLT_ENABLE_NTLS) target_link_libraries(ntls_http_server PRIVATE ws2_32 mswsock) target_link_libraries(ntls_http_client PRIVATE ws2_32 mswsock) endif() endif() ``` -------------------------------- ### Manual Integration of Yalantinglibs (C++) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/guide/what_is_yalantinglibs.md This guide provides instructions for manually integrating Yalantinglibs into a C++ project without using CMake. It covers adding include directories, enabling C++20, and specifying necessary linker flags like `-pthread` and `-ldl`, along with the `-fcoroutines` flag for GCC 10+. ```cpp // 1. Add include/ directory to include path // 2. Add include/ylt/thirdparty to include path // 3. Add include/ylt/standalone to include path // 4. Enable C++20 standard: -std=c++20 (g++/clang++) or /std:c++20 (msvc) // 5. Add link options: -pthread -ldl (for g++) // For g++ 10+, add -fcoroutines ``` -------------------------------- ### Initialize DoxygenAwesome Components Source: https://github.com/alibaba/yalantinglibs/blob/main/website/doxy/header.html Initializes various DoxygenAwesome components for enhanced documentation presentation. These components include a fragment copy button, dark mode toggle, paragraph link functionality, and an interactive table of contents. No specific input or output is detailed, but it's assumed they modify the DOM for presentation. ```javascript DoxygenAwesomeFragmentCopyButton.init() DoxygenAwesomeDarkModeToggle.init() DoxygenAwesomeParagraphLink.init() DoxygenAwesomeInteractiveToc.init() ``` -------------------------------- ### Start CoroRPC Server Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_introduction.md Initializes and starts a coro_rpc server. It registers the 'echo' RPC function and begins listening on port 9000. The server runs in a blocking wait mode. ```cpp #include "rpc_service.hpp" #include int main() { coro_rpc_server server(/*thread_num =*/10, /*port =*/9000); server.register_handler(); // register rpc function server.start(); // start the server and blocking wait } ``` -------------------------------- ### C++ Struct Pack Type Hashing Example Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/struct_pack/struct_pack_type_system.md Conceptual example illustrating how struct_pack generates a type tree and computes a compile-time MD5 hash for type checking during serialization and deserialization. This ensures data integrity by matching types between operations. ```cpp struct dummy { int32_t id; double number; std::string str; }; // At compile time, struct_pack would: // 1. Build a type tree for 'dummy'. // 2. Generate a type string from the tree. // 3. Compute a 32-bit MD5 hash of the string. // This hash is stored in the serialized data header for verification. ``` -------------------------------- ### CoroHttpClient POST Request and Response Handling (C++) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/zh/coro_http/coro_http_introduction.md Demonstrates how to use the CoroHttpClient class to send a POST request with text content and process the response. It includes sending data to a local server and asserting that the response body is not empty. Dependencies include the CoroHttpClient class and iostream for output. ```cpp coro_http_client client_all; resp_random = client_all.post("http://127.0.0.1:8093/", "test content", req_content_type::text); std::cout << resp_random.resp_body << "\n"; assert(!resp_random.resp_body.empty()); ``` -------------------------------- ### Activate RDMA Connection (C++) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_client.md Demonstrates two ways to activate an RDMA connection using `coro_rpc_client`. The first uses default RDMA configuration, while the second allows specifying custom buffer counts. The third example shows how to initialize the client with RDMA configuration through `init_config`. ```cpp coro_rpc_client cli; cli.init_ibv(); // Use default configuration cli.init_ibv({.recv_buffer_cnt=8}); // Use custom configuration ``` ```cpp coro_rpc_client cli; cli.init_config(config{.socket_config=ib_socket_t::config_t{}}) ``` -------------------------------- ### Configure Multi-Address Listening for coro_rpc Server (C++) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Illustrates how to configure the coro_rpc server to listen on multiple network interfaces simultaneously. This is achieved by populating the `acceptors` vector within the `config_t` with multiple `tcp_server_acceptor` instances, each bound to a specific address and port. The `config_t` is then passed to the `coro_rpc_server` constructor. ```cpp std::vector> acceptors; acceptors.emplace_back( std::make_unique("0.0.0.0", 8824)); acceptors.emplace_back( std::make_unique("localhost", 8825)); coro_rpc_server server( coro_rpc::config_t{.acceptors = std::move(acceptors)}); ``` -------------------------------- ### CMake Integration with yalantinglibs using FetchContent Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/guide/what_is_yalantinglibs.md This snippet demonstrates how to integrate the yalantinglibs project into your CMake build system using the FetchContent module. It clones the repository, makes it available, and links the library to your executable. It requires CMake version 3.15 or higher and enables C++20 support. ```cmake cmake_minimum_required(VERSION 3.15) project(ylt_test) include(FetchContent) FetchContent_Declare( yalantinglibs GIT_REPOSITORY https://github.com/alibaba/yalantinglibs.git GIT_TAG main GIT_SHALLOW 1 # optional ( --depth=1 ) ) FetchContent_MakeAvailable(yalantinglibs) add_executable(main main.cpp) target_link_libraries(main yalantinglibs::yalantinglibs) target_compile_features(main PRIVATE cxx_std_20) ``` -------------------------------- ### Registering Member Functions for RPC (Server-Side) Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_server.md Demonstrates how to register member functions of a class for RPC handling on the server. This includes regular member functions, coroutine member functions, and member functions using callbacks. Ensure the object's lifecycle is managed to prevent undefined behavior. ```cpp #include "rpc_service.h" #include struct dummy { std::string_view echo(std::string_view str) { return str; } Lazy coroutine_echo(std::string_view str) {co_return str;} void callback_echo(coro_rpc::context ctx, std::string_view str) { ctx.response_msg(str); } }; int main() { coro_rpc_server server; dummy d{}; server.register_handler<&dummy::echo,&dummy::coroutine_echo,&dummy::callback_echo>(&d); // regist member function server.start(); } ``` -------------------------------- ### C++ XML Serialization/Deserialization with struct_xml Source: https://github.com/alibaba/yalantinglibs/blob/main/README.md Provides an example of converting C++ structs to XML and vice versa using the struct_xml library. It includes necessary headers xml_reader.h and xml_writer.h. The example showcases basic usage with a 'person' struct and asserts the correctness of the conversion. ```cpp #include "ylt/struct_xml/xml_reader.h" #include "ylt/struct_xml/xml_writer.h" struct person { std::string name; int age; }; // static reflection works in C++20. In C++17 we need add macro manually // YLT_REFL(person, name, age); void basic_usage() { std::string xml = R"( tom 20 )"; person p; bool r = struct_xml::from_xml(p, xml.data()); assert(r); assert(p.name == "tom" && p.age == 20); std::string str; r = struct_xml::to_xml_pretty(p, str); assert(r); std::cout << str; } ``` -------------------------------- ### gRPC Asynchronous Client Example in C++ Source: https://github.com/alibaba/yalantinglibs/blob/main/website/docs/en/coro_rpc/coro_rpc_introduction.md Demonstrates how to implement an asynchronous gRPC client in C++. It utilizes std::mutex and std::condition_variable for managing asynchronous callback completion. This example showcases sending a 'SayHello' request and handling the response asynchronously. ```cpp // std::string SayHello(const std::string& user) { // Data we are sending to the server. HelloRequest request; request.set_name(user); // Container for the data we expect from the server. HelloReply reply; // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. ClientContext context; // The actual RPC. std::mutex mu; std::condition_variable cv; bool done = false; Status status; stub_->async()->SayHello(&context, &request, &reply, [&mu, &cv, &done, &status](Status s) { status = std::move(s); std::lock_guard lock(mu); done = true; cv.notify_one(); }); std::unique_lock lock(mu); while (!done) { cv.wait(lock); } // Act upon its status. if (status.ok()) { return reply.message(); } else { std::cout << status.error_code() << ": " << status.error_message() << std::endl; return "RPC failed"; } } ```