diff --git a/CMakeLists.txt b/CMakeLists.txt index 22ba8494f..430bc747d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,7 +181,7 @@ if(AIMRT_BUILD_WITH_ROS2) endif() if(AIMRT_BUILD_RUNTIME) - include(GetBoost) + include(GetAsio) include(GetGFlags) include(GetYamlCpp) include(GetTBB) @@ -207,13 +207,28 @@ if(AIMRT_BUILD_RUNTIME) endif() endif() + if(AIMRT_BUILD_NET_PLUGIN) + include(GetBoost) + endif() + if(AIMRT_BUILD_RECORD_PLAYBACK_PLUGIN) include(GetSqlite) endif() if(AIMRT_BUILD_ICEORYX_PLUGIN) - include(GetCppToml) - include(GetIceoryx) + # try to find libacl + if(CMAKE_SYSTEM_NAME MATCHES "Linux|QNX") + find_library(ACL_LIB acl) + if(NOT ACL_LIB) + message(WARNING "ICEORYX PLUGIN: libacl1-dev not found, please install the package by: sudo apt install libacl1-dev.") + set(AIMRT_BUILD_ICEORYX_PLUGIN OFF) + endif() + endif() + + if(AIMRT_BUILD_ICEORYX_PLUGIN) + include(GetCppToml) + include(GetIceoryx) + endif() endif() if(AIMRT_BUILD_MQTT_PLUGIN) @@ -232,7 +247,9 @@ if(AIMRT_BUILD_RUNTIME) message(STATUS "Rust compiler (rustc) found: ${rustc_output}") include(GetZenoh) else() - message(WARNING "Rust compiler (rustc) not found, will not compile zenoh plugin. Please install Rust environment referring to https://www.rust-lang.org/tools/install.") + message( + WARNING + "ZENOH_PLUGIN: Rust compiler (rustc) not found, will not compile zenoh plugin. Please install Rust environment referring to https://www.rust-lang.org/tools/install.") set(AIMRT_BUILD_ZENOH_PLUGIN OFF) endif() endif() @@ -245,6 +262,7 @@ if(AIMRT_BUILD_RUNTIME) endif() if(AIMRT_BUILD_GRPC_PLUGIN) + include(GetBoost) include(GetNghttp2) endif() endif() @@ -269,3 +287,24 @@ if(AIMRT_INSTALL AND AIMRT_BUILD_PYTHON_PACKAGE) install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_BINARY_DIR}\" --config ${CMAKE_BUILD_TYPE} --target create_python_pkg)") endif() + +# print all aimrt options +message("\n\n AIMRT CMake Options/Info:") +get_cmake_property(all_variables VARIABLES) +set(printed_vars) + +foreach(var ${all_variables}) + if(var MATCHES "^AIMRT_.*") + if(NOT "${var}" IN_LIST printed_vars) + list(APPEND printed_vars "${var}") + string(LENGTH ${var} var_length) + math(EXPR padding_length "40 - ${var_length}") + if(padding_length GREATER 0) + string(REPEAT "-" ${padding_length} padding) + else() + set(padding "") + endif() + message(" ${var}${padding}: ${${var}}") + endif() + endif() +endforeach() diff --git a/cmake/GetAsio.cmake b/cmake/GetAsio.cmake new file mode 100644 index 000000000..317eb42b3 --- /dev/null +++ b/cmake/GetAsio.cmake @@ -0,0 +1,70 @@ +# Copyright (c) 2023, AgiBot Inc. +# All rights reserved. + +include(FetchContent) + +message(STATUS "get asio ...") + +set(asio_DOWNLOAD_URL + "https://github.com/chriskohlhoff/asio/archive/asio-1-30-2.tar.gz" + CACHE STRING "") + +if(asio_LOCAL_SOURCE) + FetchContent_Declare( + asio + SOURCE_DIR ${asio_LOCAL_SOURCE} + OVERRIDE_FIND_PACKAGE) +else() + FetchContent_Declare( + asio + URL ${asio_DOWNLOAD_URL} + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + OVERRIDE_FIND_PACKAGE) +endif() + +FetchContent_GetProperties(asio) +if(NOT asio_POPULATED) + FetchContent_Populate(asio) + + add_library(asio INTERFACE) + add_library(asio::asio ALIAS asio) + + target_include_directories(asio INTERFACE ${asio_SOURCE_DIR}/asio/include) + target_compile_definitions(asio INTERFACE ASIO_STANDALONE ASIO_NO_DEPRECATED) + + find_package(Threads REQUIRED) + target_link_libraries(asio INTERFACE Threads::Threads) + + if(WIN32) + # macro see @ https://stackoverflow.com/a/40217291/1746503 + macro(get_win32_winnt version) + if(CMAKE_SYSTEM_VERSION) + set(ver ${CMAKE_SYSTEM_VERSION}) + string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver}) + string(REGEX MATCH "^([0-9]+)" verMajor ${ver}) + # Check for Windows 10, b/c we'll need to convert to hex 'A'. + if("${verMajor}" MATCHES "10") + set(verMajor "A") + string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver}) + endif("${verMajor}" MATCHES "10") + # Remove all remaining '.' characters. + string(REPLACE "." "" ver ${ver}) + # Prepend each digit with a zero. + string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver}) + set(${version} "0x${ver}") + endif() + endmacro() + + if(NOT DEFINED _WIN32_WINNT) + get_win32_winnt(ver) + set(_WIN32_WINNT ${ver}) + endif() + + message(STATUS "Set _WIN32_WINNET=${_WIN32_WINNT}") + + target_compile_definitions(asio INTERFACE _WIN32_WINNT=${_WIN32_WINNT} WIN32_LEAN_AND_MEAN) + endif() +endif() + +# import targets: +# asio::asio diff --git a/cmake/GetJsonCpp.cmake b/cmake/GetJsonCpp.cmake index d6dc20139..ba48fcc05 100644 --- a/cmake/GetJsonCpp.cmake +++ b/cmake/GetJsonCpp.cmake @@ -6,7 +6,7 @@ include(FetchContent) message(STATUS "get jsoncpp ...") set(jsoncpp_DOWNLOAD_URL - "https://github.com/open-source-parsers/jsoncpp/archive/1.9.5.tar.gz" + "https://github.com/open-source-parsers/jsoncpp/archive/1.9.6.tar.gz" CACHE STRING "") if(jsoncpp_LOCAL_SOURCE) diff --git a/cmake/GetOpenTelemetryCpp.cmake b/cmake/GetOpenTelemetryCpp.cmake index c7cca5893..aaff2f994 100644 --- a/cmake/GetOpenTelemetryCpp.cmake +++ b/cmake/GetOpenTelemetryCpp.cmake @@ -48,6 +48,10 @@ if(NOT opentelemetry_cpp_POPULATED) ON CACHE BOOL "") + set(WITH_STL + "CXX20" + CACHE STRING "") + set(OTELCPP_PROTO_PATH ${opentelemetry_proto_SOURCE_DIR} CACHE PATH "") diff --git a/document/sphinx-cn/conf.py b/document/sphinx-cn/conf.py index f5581ba70..7a9388c12 100644 --- a/document/sphinx-cn/conf.py +++ b/document/sphinx-cn/conf.py @@ -56,5 +56,5 @@ myst_enable_extensions = [ myst_substitutions = { "code_site_url": "https://github.com/AimRT/AimRT", - "code_site_root_path_url": "https://github.com/AimRT/AimRT/blob/master", + "code_site_root_path_url": "https://github.com/AimRT/AimRT/blob/main", } diff --git a/document/sphinx-cn/release_notes/v0_9_0.md b/document/sphinx-cn/release_notes/v0_9_0.md index f3a5225e1..4a51d6fc9 100644 --- a/document/sphinx-cn/release_notes/v0_9_0.md +++ b/document/sphinx-cn/release_notes/v0_9_0.md @@ -5,10 +5,12 @@ - 优化了 zenoh 插件: - 添加了 zenoh rpc 后端; - 现在可以传入 zenoh 原生配置; -- mqtt 新增配置项以支持加密传输 - +- mqtt 新增配置项以支持加密传输; +- 新增了第三方库 asio,runtime::core 不再引用 boost,改为引用独立的 asio 库,以减轻依赖; **次要修改**: - 缩短了一些 examples 的文件路径长度; - 修复了一些轻微问题; +- 优化代码结构,移动代码 src/runtime/common/net 至新位置 src/common/net; +- 升级 jsoncpp 至 1.9.6 版本以优化一些 cmake 问题; diff --git a/document/sphinx-cn/tutorials/concepts/cmake.md b/document/sphinx-cn/tutorials/concepts/cmake.md index d0a14a8f6..8095f1886 100644 --- a/document/sphinx-cn/tutorials/concepts/cmake.md +++ b/document/sphinx-cn/tutorials/concepts/cmake.md @@ -73,6 +73,7 @@ AimRT 中所有的可引用的非协议类型 CMake Target 如下: | CMake Target名称 | 作用 | 需要开启的宏 | | ---- | ---- | ---- | | aimrt::common::util | 一些独立基础工具,如 string、log 等 | | +| aimrt::common::net | 一些独立的网络工具,基于 boost asio/beast | AIMRT_BUILD_RUNTIME、AIMRT_BUILD_NET_PLUGIN 或 AIMRT_BUILD_GRPC_PLUGIN | | aimrt::common::ros2_util | 独立的 ros2 相关的基础工具 | AIMRT_BUILD_WITH_ROS2 | | aimrt::interface::aimrt_module_c_interface | 模块开发接口-C 版本 | | | aimrt::interface::aimrt_module_cpp_interface | 模块开发接口-CPP 版本 | | diff --git a/document/sphinx-cn/tutorials/concepts/concepts.md b/document/sphinx-cn/tutorials/concepts/concepts.md index 3f6653a7f..35ed27be5 100644 --- a/document/sphinx-cn/tutorials/concepts/concepts.md +++ b/document/sphinx-cn/tutorials/concepts/concepts.md @@ -75,7 +75,7 @@ AimRT 目前官方支持两种 IDL: `Channel`也叫数据通道,是一种典型的通信拓补概念,其通过`Topic`标识单个数据通道,由发布者`Publisher`和订阅者`Subscriber`组成,订阅者可以获取到发布者发布的数据。`Channel`是一种多对多的拓补结构,`Module`可以向任意数量的`Topic`发布数据,同时可以订阅任意数量的`Topic`。类似的概念如 ROS 中的 Topic、Kafka/RabbitMQ 等消息队列。 -在 AimRT 中,Channel 由`接口层`和`后端`两部分组成,两者相互解耦。接口层定义了一层抽象的 Api,表示逻辑层面上的`Channel`;而后端负责实际的 Channel 数据传输,可以有多种类型。AimRT 官方提供了一些 Channel 后端,例如 mqtt、ros 等,使用者也可以自行开发新的 Channel 后端。 +在 AimRT 中,Channel 由`接口层`和`后端`两部分组成,两者相互解耦。接口层定义了一层抽象的 Api,表示逻辑层面上的`Channel`;而后端负责实际的 Channel 数据传输,可以有多种类型。AimRT 官方提供了一些 Channel 后端,例如 mqtt、ros2 等,使用者也可以自行开发新的 Channel 后端。 开发者在使用 AimRT 中的 Channel 功能时,先在业务逻辑层调用接口层的 API,往某个 Topic 中发布数据,或订阅某个 Topic 的数据。然后 AimRT 框架会根据一定的规则,选择一个或几个 Channel 后端进行处理,这些后端将数据通过一些特定的方式发送给其他节点,由其他节点上对应的 Channel 后端接收数据并传递给业务逻辑层。整个逻辑流程如下图所示: @@ -85,7 +85,7 @@ AimRT 目前官方支持两种 IDL: ## AimRT 中的 "Rpc" 概念 `RPC`也叫远程过程调用,基于请求-回复模型,由客户端`Client`和服务端`Server`组成,`Module`可以创建客户端句柄,发起特定的 RPC 请求,由其指定的、或由框架根据一定规则指定的服务端来接收请求并回复。`Module`也可以创建服务端句柄,提供特定的 RPC 服务,接收处理系统路由过来的请求并回复。类似的概念如 ROS 中的 Services、GRPC/Thrift 等 RPC 框架。 -在 AimRT 中,RPC 也由`接口层`和`后端`两部分组成,两者相互解耦。接口层定义了 RPC 的抽象 Api,而后端则负责实际的 RPC 调用。AimRT 官方提供了一些 RPC 后端,例如 http、ros 等,使用者也可以自行开发新的 RPC 后端。 +在 AimRT 中,RPC 也由`接口层`和`后端`两部分组成,两者相互解耦。接口层定义了 RPC 的抽象 Api,而后端则负责实际的 RPC 调用。AimRT 官方提供了一些 RPC 后端,例如 http、ros2 等,使用者也可以自行开发新的 RPC 后端。 开发者使用 AimRT 的 RPC 功能时,先在业务逻辑层调用接口层 API,通过 Client 发起一个 RPC 调用,AimRT 框架会根据一定的规则选择一个 RPC 后端进行处理,它将数据通过一些特定的方式发送给 Server 节点,由 Server 节点上对应的 Rpc 后端接收数据并传递给业务层,并将业务层的回包传递回 Client 端。整个逻辑流程如下图所示: diff --git a/document/sphinx-cn/tutorials/quick_start/build_from_source_ubuntu.md b/document/sphinx-cn/tutorials/quick_start/build_from_source_ubuntu.md new file mode 100644 index 000000000..08fc9b0cf --- /dev/null +++ b/document/sphinx-cn/tutorials/quick_start/build_from_source_ubuntu.md @@ -0,0 +1,184 @@ +# Ubuntu 22.04 源码构建 + +## 必选依赖 + +### CMake + +AimRT 编译所需的最小 CMake 版本为 3.24,Ubuntu 22.04 使用 apt 包管理器安装的 CMake 版本为 3.22 不符合要求,请前往 [CMake 官方网站](https://cmake.org/download/) 下载对应版本进行安装。 + +推荐的安装方式有两种 + +1. 通过 pip 安装 CMake + +```bash +sudo apt install python3 python3-pip +pip install cmake --upgrade +``` + +2. 安装 CMake 官方提供的安装脚本 + +```bash +wget https://github.com/Kitware/CMake/releases/download/v3.30.4/cmake-3.30.4-linux-x86_64.sh +sudo bash cmake-3.30.4-linux-x86_64.sh --prefix=/usr/local --skip-license +``` + +### make/gcc/g++ + +Ubuntu 22.04 中 apt 源自带的 gcc 版本为 11.4,适用于 AimRT 构建所用,可以直接安装 + +```bash +sudo apt install make gcc g++ +``` + +## 最小化构建 + +将以上内容进行安装后即可进行无外部依赖的最小化构建,构建选项如下所示 + +```bash +cmake -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DAIMRT_INSTALL=ON \ + -DCMAKE_INSTALL_PREFIX=./build/install \ + -DAIMRT_BUILD_TESTS=OFF \ + -DAIMRT_BUILD_EXAMPLES=ON \ + -DAIMRT_BUILD_DOCUMENT=OFF \ + -DAIMRT_BUILD_RUNTIME=ON \ + -DAIMRT_BUILD_CLI_TOOLS=OFF \ + -DAIMRT_BUILD_PYTHON_RUNTIME=OFF \ + -DAIMRT_USE_FMT_LIB=ON \ + -DAIMRT_BUILD_WITH_PROTOBUF=ON \ + -DAIMRT_USE_LOCAL_PROTOC_COMPILER=OFF \ + -DAIMRT_USE_PROTOC_PYTHON_PLUGIN=OFF \ + -DAIMRT_BUILD_WITH_ROS2=OFF \ + -DAIMRT_BUILD_NET_PLUGIN=ON \ + -DAIMRT_BUILD_MQTT_PLUGIN=OFF \ + -DAIMRT_BUILD_ZENOH_PLUGIN=OFF \ + -DAIMRT_BUILD_ICEORYX_PLUGIN=OFF \ + -DAIMRT_BUILD_ROS2_PLUGIN=OFF \ + -DAIMRT_BUILD_RECORD_PLAYBACK_PLUGIN=ON \ + -DAIMRT_BUILD_TIME_MANIPULATOR_PLUGIN=ON \ + -DAIMRT_BUILD_PARAMETER_PLUGIN=ON \ + -DAIMRT_BUILD_LOG_CONTROL_PLUGIN=ON \ + -DAIMRT_BUILD_OPENTELEMETRY_PLUGIN=ON \ + -DAIMRT_BUILD_GRPC_PLUGIN=ON \ + -DAIMRT_BUILD_PYTHON_PACKAGE=OFF + +cmake --build build --config Release --target all -j +``` + +如果要开启其他选项则需要安装对应依赖,具体依赖请参考 [可选依赖](#可选依赖) + +## 可选依赖 + +### Python 功能及其相关包 + +AimRT 所使用的 Python 版本最低为 3.10,推荐使用 3.10 版本(Ubuntu 22.04 的 apt 源安装版本)。 + +AimRT 的 Python 接口依赖 Python 3。 + +```bash +sudo apt install python3 +``` + +aimrt_cli 工具依赖 Python 3 以及 pyinstaller jinja2 pyyaml 三个库,可以通过以下命令进行安装 + +```bash +sudo apt install python3 python3-pip +pip install pyinstaller jinja2 pyyaml --upgrade +``` + +打包生成 aimrt_py 的 whl 包功能依赖 Python 3 以及 build setuptools wheel 等库,可以通过以下命令进行安装 + +```bash +sudo apt install python3 python3-pip +pip install build setuptools wheel --upgrade +``` + +以上内容分别对应以下选项 + +```bash +-DAIMRT_BUILD_PYTHON_RUNTIME=ON +-DAIMRT_BUILD_CLI_TOOLS=ON +-DAIMRT_BUILD_PYTHON_PACKAGE=ON +``` + +### ROS2 相关依赖 + +AimRT 的 ROS2 相关功能以及 ROS2 插件依赖 ROS2 humble 版本(仅支持该版本),可以参考 [ROS2 官方文档](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html) 进行安装。 + +安装完成后需要设置好相应的环境变量,即 + +```bash +source /opt/ros/humble/setup.bash +``` + +可以通过以下命令检查是否设置好相应的环境变量 + +```bash +printenv | grep -i ROS +``` + +ROS2 相关依赖对应以下选项 + +```bash +-DAIMRT_BUILD_WITH_ROS2=ON +-DAIMRT_BUILD_ROS2_PLUGIN=ON +``` + +### Iceoryx 相关依赖 + +AimRT 的 Iceoryx 插件依赖 acl 库,可以通过以下命令进行安装 + +```bash +sudo apt install libacl1-dev +``` + +Iceoryx 相关依赖对应以下选项 + +```bash +-DAIMRT_BUILD_ICEORYX_PLUGIN=ON +``` + +### Zenoh 相关依赖 + +AimRT 的 Zenoh 插件依赖本地的 rust 环境,可以通过以下命令进行安装 + +```bash +sudo apt install curl +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +Zenoh 相关依赖对应以下选项 + +```bash +-DAIMRT_BUILD_ZENOH_PLUGIN=ON +``` + +### MQTT 相关依赖 + +AimRT 的 MQTT 插件依赖 openssl 库,可以通过以下命令进行安装 + +```bash +sudo apt install libssl-dev +``` + +MQTT 相关依赖对应以下选项 + +```bash +-DAIMRT_BUILD_MQTT_PLUGIN=ON +``` + +## 完整构建 + +将以上内容进行安装后即可进行完整构建,可以直接运行根目录下的 build.sh 脚本进行构建 + +```bash +./build.sh +``` + +AimRT 在构建过程中会使用 FetchContent 从 github 上拉取依赖,如果网络环境不佳,可以使用以下命令将 FetchContent 的源替换为从 gitee 镜像拉取再进行构建 + +```bash +source url_cn.bashrc +./build.sh $AIMRT_DOWNLOAD_FLAGS +``` diff --git a/document/sphinx-cn/tutorials/quick_start/build_from_source_windows.md b/document/sphinx-cn/tutorials/quick_start/build_from_source_windows.md new file mode 100644 index 000000000..8bf31fb9d --- /dev/null +++ b/document/sphinx-cn/tutorials/quick_start/build_from_source_windows.md @@ -0,0 +1,86 @@ + +# Windows 源码构建 + +注意 Windows 平台下部分插件未经过实际测试,其编译选项在 build.bat 中默认关闭,启用后可能存在问题,如果遇到问题请及时反馈。 + +## 必选依赖 + +### MSVC 编译套件 + +当前 AimRT 支持的 MSVC 编译套件版本为 1940,推荐直接安装 [Visual Studio 2022](https://visualstudio.microsoft.com/zh-hans/downloads/) 及以上版本,安装时勾选 C++ 桌面开发模块。 + +### CMake + +当前 AimRT 支持的最低 CMake 版本为 3.24,可以通过以下链接下载合适的版本进行安装: + +[CMake 3.24](https://cmake.org/download/) + +## 最小化构建 + +将以上内容进行安装后即可进行无外部依赖的最小化构建,构建选项如下所示 + +```shell +cmake -B build ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DAIMRT_INSTALL=ON ^ + -DCMAKE_INSTALL_PREFIX="./build/install" ^ + -DAIMRT_BUILD_TESTS=OFF ^ + -DAIMRT_BUILD_EXAMPLES=ON ^ + -DAIMRT_BUILD_DOCUMENT=ON ^ + -DAIMRT_BUILD_RUNTIME=ON ^ + -DAIMRT_BUILD_CLI_TOOLS=OFF ^ + -DAIMRT_BUILD_PYTHON_RUNTIME=OFF ^ + -DAIMRT_USE_FMT_LIB=ON ^ + -DAIMRT_BUILD_WITH_PROTOBUF=ON ^ + -DAIMRT_USE_LOCAL_PROTOC_COMPILER=OFF ^ + -DAIMRT_USE_PROTOC_PYTHON_PLUGIN=OFF ^ + -DAIMRT_BUILD_WITH_ROS2=OFF ^ + -DAIMRT_BUILD_NET_PLUGIN=ON ^ + -DAIMRT_BUILD_MQTT_PLUGIN=OFF ^ + -DAIMRT_BUILD_ZENOH_PLUGIN=OFF ^ + -DAIMRT_BUILD_ICEORYX_PLUGIN=OFF ^ + -DAIMRT_BUILD_ROS2_PLUGIN=OFF ^ + -DAIMRT_BUILD_RECORD_PLAYBACK_PLUGIN=ON ^ + -DAIMRT_BUILD_TIME_MANIPULATOR_PLUGIN=ON ^ + -DAIMRT_BUILD_PARAMETER_PLUGIN=ON ^ + -DAIMRT_BUILD_LOG_CONTROL_PLUGIN=ON ^ + -DAIMRT_BUILD_OPENTELEMETRY_PLUGIN=OFF ^ + -DAIMRT_BUILD_GRPC_PLUGIN=OFF ^ + -DAIMRT_BUILD_PYTHON_PACKAGE=OFF +``` + +## 可选依赖 + +### Python 及其相关包 + +AimRT 在 Windows 平台下支持的 Python 版本最低为 3.11,推荐使用 [Python 3.11](https://www.python.org/downloads/release/python-31110/) 及以上版本。 + +安装完成后需要将 Python 添加到系统环境变量中。 + +airmt_cli 工具依赖于 Python 3 以及 pyinstaller jinja2 pyyaml 三个库,可以通过以下命令进行安装 + +```shell +pip install pyinstaller jinja2 pyyaml --upgrade +``` + +打包生成 aimrt_py 的 whl 包功能依赖 Python 3 以及 build setuptools wheel 等库,可以通过以下命令进行安装 + +```shell +pip install build setuptools wheel --upgrade +``` + +以上内容分别对应以下选项 + +```shell +-DAIMRT_BUILD_PYTHON_RUNTIME=ON +-DAIMRT_BUILD_CLI_TOOLS=ON +-DAIMRT_BUILD_PYTHON_PACKAGE=ON +``` + +## 完整构建 + +此处完整构建不包含未经充分测试的插件,直接运行 build.bat 即可。 + +```shell +./build.bat +``` diff --git a/document/sphinx-cn/tutorials/quick_start/installation_cpp.md b/document/sphinx-cn/tutorials/quick_start/installation_cpp.md index 76c9e5e66..c648beb44 100644 --- a/document/sphinx-cn/tutorials/quick_start/installation_cpp.md +++ b/document/sphinx-cn/tutorials/quick_start/installation_cpp.md @@ -1,19 +1,10 @@ -# 引用与安装(CPP) +# 安装与引用(CPP) +## 系统要求 -在开发 C++ 工程时,您可以通过两种方式引用 AimRT: -- [推荐] 基于 CMake FetchContent,通过源码进行引用; -- 安装后,基于 CMake find_package 进行引用; - -AimRT 比较轻量,推荐用户直接基于源码进行引用。如果要使用基于安装的方式进行引用,AimRT 也提供了两种方式: -- 从源码编译安装; -- 二进制安装; - - -## 编译环境要求 -AimRT 兼容 linux、windows 等主流操作系统,编译器需要能够支持 c++20,CMake 版本需要 3.24 或以上。我们已经在以下操作系统和编译器上测试过: -- Ubuntu22.04 +当前 AimRT 官方支持的操作系统和编译套件包括: +- Ubuntu 22.04 - gcc-11.4 - gcc-12.4 - gcc-13.3 @@ -21,20 +12,34 @@ AimRT 兼容 linux、windows 等主流操作系统,编译器需要能够支持 - clang-16.0.6 - clang-17.0.6 - clang-18.1.8 -- Windows11 - - MSVC-19.40 +- Windows + - MSVC-1940 -请注意: -- 在编译构建时,AimRT 可能通过源码方式引用一些第三方依赖,如果出现网络问题,可以参考[CMake](../concepts/cmake.md)文档进行处理。 -- 在打开某些选项、编译某些插件时,AimRT 可能需要额外引用一些第三方依赖,细节请参考对应插件的文档、CMake 代码文件或构建时的提示。以下是一些示例: - - 如果要编译 ROS2 相关接口/插件,AimRT 会通过`find_package`的方式在本地寻找 rclcpp 等依赖,请确保本地安装有[ROS2 Humble](https://docs.ros.org/en/humble/)。 - - 如果要构建 Python 接口、cli 工具等,AimRT 会通过`find_package`的方式在本地寻找 Python 依赖,请确保本地安装有 Python3 及相关的 python 包,缺失相应包在 CMake 生成过程中会告警不会编译相应内容。 - - Zenoh 插件需要本地安装有 rust 环境,在 Ubuntu 上可通过 `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` 进行安装,没有 rust 环境则不会编译 zenoh 插件。 - - Iceoryx 插件依赖 libacl,在 ubuntu 上可通过 `sudo apt install libacl1-dev` 进行安装,选项开启但缺失相应包会报错。 - - Boost 依赖由于其内容较大,CMake 会首先检查本地是否有 1.82.0 及以上版本的 boost,如果有则使用本地安装的 boost,如果没有则进行下载。 +除以上列出的系统外,理论上所有兼容以上环境的系统均可以编译运行 AimRT。 +Ubuntu 22.04 为推荐系统,所有测试以及二进制包均基于此系统,Windows 平台下仅支持 MSVC 编译器且插件支持较为有限。 -## 通过源码引用 +ROS2 相关内容目前仅支持 humble 版本。 + +## 安装方式 + +当前 AimRT 的 C++ 接口仅支持从源码构建安装。 + +### 源码构建 + +[Ubuntu Linux 22.04 源码构建](build_from_source_ubuntu.md) + +[Windows 源码构建](build_from_source_windows.md) + +## 引用方式 + +在开发 C++ 工程时,您可以通过两种方式引用 AimRT: +- [推荐] 基于 CMake FetchContent,通过源码进行引用; +- 安装后,基于 CMake find_package 进行引用; + +AimRT 比较轻量,推荐用户直接基于源码进行引用。 + +### 通过源码引用 您可以参考以下 CMake 代码引用 AimRT,注意需要将`GIT_TAG`版本改为你想引用的版本: ```cmake @@ -62,37 +67,11 @@ target_link_libraries( PUBLIC aimrt::interface::aimrt_module_cpp_interface) ``` -## 安装后find_package引用 +### 安装后find_package引用 请注意:使用 **install 后 find_package 引用**这种方式,只能引用部分功能,只能基于 pkg 模式开发,无法使用 app 模式开发、或开发 aimrt 插件。 -### 安装方式一:从源码构建安装 - -基于源码编译 AimRT 非常简单,可参考以下步骤: -- 首先请确认本地环境符合要求; -- 通过 git 等方式下载源码; -- 直接执行 AimRT 源码根路径下的 build 脚本执行编译、安装; - - linux 下请执行 build.sh; - - windows 下请执行 build.bat; - - 可以修改 build 脚本中的 CMake 选项以开关一些功能; - - 可以修改 build 脚本中的`CMAKE_INSTALL_PREFIX`选项指定安装地址; - - 如果遇到网络问题无法下载一些依赖,请参考[AimRT中的CMake](../concepts/cmake.md)文档中的说明; - - -### 安装方式二:从二进制包安装 - -***TODO*** - - - - -### 安装完成后,使用CMake find_package进行引用 - -完成安装后,参考以下步骤完成引用: +参考 [源码构建](build_from_source_ubuntu.md) 运行 build.sh 脚本进行构建,在构建时可以修改 `CMAKE_INSTALL_PREFIX` 指定安装目录,完成安装后,参考以下步骤完成引用: - 如果没有安装在系统路径,则需要在自己项目的 CMake 中设置 CMAKE_PREFIX_PATH 到 AimRT 的安装目录,例如: ```cmake list(APPEND CMAKE_PREFIX_PATH "/path/to/aimrt/install") diff --git a/document/sphinx-cn/tutorials/quick_start/installation_py.md b/document/sphinx-cn/tutorials/quick_start/installation_py.md index 60e61431e..15b7728dc 100644 --- a/document/sphinx-cn/tutorials/quick_start/installation_py.md +++ b/document/sphinx-cn/tutorials/quick_start/installation_py.md @@ -12,10 +12,10 @@ AimRT官方测试过的最低 Python 版本是 3.10,Linux 系统 glibc 的最 我们在以下系统和 python 版本上测试过 `aimrt_py` 包: -- Ubuntu22.04 - - python3.10 -- Windows11 - - python3.11 +- Ubuntu 22.04 + - python 3.10 +- Windows 10 + - python 3.11 请注意,如果您想要使用 AimRT-Python 中的 RPC 或 Channel 功能,当前只支持以 protobuf 作为协议,在使用时需要在本地安装有 protobuf python 包,您可以通过 `pip install protobuf` 来安装。 @@ -28,109 +28,11 @@ AimRT官方测试过的最低 Python 版本是 3.10,Linux 系统 glibc 的最 ## 二进制安装 -***TODO*** - - +您可以直接在 [AimRT 的发布页面](https://github.com/AimRT/AimRT/releases) 中找到 aimrt_py 的 whl 文件,通过 pip 安装。 ## 源码编译安装 -首先通过 git 等方式下载源码,然后基于 CMake 进行构建编译,构建完成后在 build/aimrt_py_package/dist 路径下有 aimrt_py 的 whl 文件,最后通过 pip 安装。 - -以下是在 Linux 平台(以 Ubuntu 22.04 为例)和 Windows 平台(使用 MSVC 工具链)上的编译安装方法。 - -### Linux 平台(以 Ubuntu 22.04 为例) - -1. 下载源码 -2. 安装编译依赖 - - 全量编译本项目需要安装 ros2(humble 版本,安装指引见 [ros2 installation](https://docs.ros.org/en/humble/Installation.html)),如果您不需要使用 ros2 插件可以在 build.sh 文件中将以下选项更改为 OFF: - - ```bash - -DAIMRT_BUILD_WITH_ROS2=ON \ - -DAIMRT_BUILD_ROS2_PLUGIN=ON \ - # ... - ``` - - 为支持打包为 .whl 文件,需要安装 python 模块 build、 setuptools 和 wheel,其中 setuptools 最低要求版本为 61.0,推荐直接安装最新版本,可以使用如下命令安装 - - ```bash - pip install build setuptools wheel --upgrade - ``` - -3. 安装编译工具链 - - 为编译项目还需要安装 CMake 和 make,可以使用如下命令安装 - - ```bash - sudo apt install cmake make - ``` - - CMake 的最低版本要求为 3.24,如果系统中的版本低于 3.24,可以到 [CMake 官网](https://cmake.org/download/) 下载最新版本的 CMake 并安装。 - - 编译项目还需要使用编译器,推荐使用 GCC 11.4 或更高版本,在 Ubuntu 22.04 上可以使用如下命令安装 - - ```bash - sudo apt install gcc g++ - ``` - - 如果您的 gcc 版本低于 11.4,可以到 [GCC 官网](https://gcc.gnu.org/) 下载最新版本的 GCC 并安装。 - -4. 执行 build.sh 脚本编译生成 .whl 文件 - - 进入 aimrt 项目文件夹,执行 build.sh 脚本,命令如下 - - ```bash - ./build.sh - ``` - - 编译完成后可以在 `build/aimrt_py_pkg/dist` 目录下找到 `aimrt_py*.whl` 文件,使用不同的 python 环境、系统架构和仓库版本文件名会略有不同,例如使用 CPython3.10 在 x86_64 架构下编译 0.7.0 版本仓库生成的文件名为 `aimrt_py-0.7.0-cp310-cp310-linux_x86_64.whl`。 - -5. 使用 pip 安装 .whl 文件 - - 使用 pip 安装编译生成的 .whl 文件,命令如下 - - ```bash - pip install build/aimrt_py_pkg/dist/aimrt_py*.whl - ``` - - 安装完成后即可使用 aimrt_py 包。 - -### Windows 平台 (使用 MSVC 工具链) - -1. 下载源码 -2. 安装编译依赖 - - Windows 平台不支持 ros2、mqtt、opentelemetry 插件,build.bat 文件中默认关闭了这些插件。 - - 为支持打包为 .whl 文件,需要安装 python 模块 build 和 setuptools,可以使用如下命令安装 - - ```shell - pip install build setuptools - ``` - -3. 安装编译工具链 - - 为编译项目还需要安装 Visual Studio 2019 或 Visual Studio 2022(推荐),可以到 [Visual Studio 官网](https://visualstudio.microsoft.com/zh-hans/vs/) 下载并安装。 - -4. 执行 build.bat 脚本编译生成 .whl 文件 - - 在 Command Prompt 中,进入 aimrt 项目文件夹,执行 build.bat 脚本,命令如下: - - ```shell - ./build.bat - ``` - - 编译完成后可以在 `build\aimrt_py_pkg\dist` 目录下找到 `aimrt_py*.whl` 文件,使用不同的 python 环境、系统架构和仓库版本文件名会略有不同,例如使用 CPython3.10 在 x86_64 架构下编译 0.7.0 版本仓库生成的文件名为 `aimrt_py-0.7.0-cp310-cp310-win_amd64.whl`。 - -5. 使用 pip 安装 .whl 文件 - - 使用 pip 安装编译生成的 .whl 文件,命令如下 - - ```shell - pip install build\aimrt_py_pkg\dist\aimrt_py*.whl - ``` - - 安装完成后即可使用 aimrt_py 包。 +首先通过 git 等方式下载源码,然后参考 [Ubuntu 源码构建](build_from_source_ubuntu.md)/ [Windows 源码构建](build_from_source_windows.md) 进行构建编译,构建完成后在 build/aimrt_py_pkg/dist 路径下有 aimrt_py 的 whl 文件,最后通过 pip 安装。 ## 插件安装说明 @@ -144,6 +46,6 @@ ls -l $(pip show aimrt_py | grep Location | awk '{print $2 "/aimrt_py"}') 该命令会显示安装路径下的所有文件,其中文件名后缀以 plugin 结尾的文件即为插件文件(linux 下为 `*_plugin.so`, windows 下为 `*_plugin.dll`)。 -PyPI 安装方式中不含 mqtt、ros2 等插件,如果需要使用这些插件,可以通过源码编译或者下载二进制的方式安装。 + Windows 平台暂不支持 ros2、mqtt、opentelemetry 等插件。 diff --git a/format.sh b/format.sh index de3221497..1efc28ab1 100755 --- a/format.sh +++ b/format.sh @@ -19,5 +19,5 @@ echo "clang-format done" echo "cmake-format done" # autopep8, apt install python3-autopep8 -{ find . -maxdepth 1 -name "*.py" -print; find ./src -name "*.py" -print; } | xargs autopep8 -i --global-config ./.pycodestyle +{ find . -maxdepth 1 -name "*.py" ! -name "*pb2.py" -print; find ./src -name "*.py" ! -name "*pb2.py" -print; } | xargs autopep8 -i --global-config ./.pycodestyle echo "python format done" diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index e3e2bef46..0612aba31 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -8,3 +8,9 @@ add_subdirectory(util) if(AIMRT_BUILD_WITH_ROS2) add_subdirectory(ros2_util) endif() + +if(AIMRT_BUILD_RUNTIME) + if(AIMRT_BUILD_NET_PLUGIN OR AIMRT_BUILD_GRPC_PLUGIN) + add_subdirectory(net) + endif() +endif() diff --git a/src/runtime/common/net/CMakeLists.txt b/src/common/net/CMakeLists.txt similarity index 100% rename from src/runtime/common/net/CMakeLists.txt rename to src/common/net/CMakeLists.txt diff --git a/src/runtime/common/net/asio_http_cli.h b/src/common/net/asio_http_cli.h similarity index 98% rename from src/runtime/common/net/asio_http_cli.h rename to src/common/net/asio_http_cli.h index a383ad325..033becb59 100644 --- a/src/runtime/common/net/asio_http_cli.h +++ b/src/common/net/asio_http_cli.h @@ -16,7 +16,7 @@ #include "util/log_util.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioHttpClient : public std::enable_shared_from_this { public: @@ -322,6 +322,10 @@ class AsioHttpClient : public std::enable_shared_from_this { if (first_time_entry_) [[unlikely]] { first_time_entry_ = false; + AIMRT_TRACE("Http cli session create a new connect to {}:{}", + session_options_ptr_->host, + session_options_ptr_->service); + // resolve asio::ip::tcp::resolver resolver(session_socket_strand_); auto const dst = co_await resolver.async_resolve( @@ -604,4 +608,4 @@ class AsioHttpClientPool std::unordered_map> client_map_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_http_svr.h b/src/common/net/asio_http_svr.h similarity index 99% rename from src/runtime/common/net/asio_http_svr.h rename to src/common/net/asio_http_svr.h index 5cbff6c1d..859ae4d98 100644 --- a/src/runtime/common/net/asio_http_svr.h +++ b/src/common/net/asio_http_svr.h @@ -18,7 +18,7 @@ #include "util/string_util.h" #include "util/url_parser.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioHttpServer : public std::enable_shared_from_this { public: @@ -822,4 +822,4 @@ class AsioHttpServer : public std::enable_shared_from_this { std::list> session_ptr_list_; // session池 }; -} // namespace aimrt::runtime::common::net \ No newline at end of file +} // namespace aimrt::common::net \ No newline at end of file diff --git a/src/runtime/common/net/asio_http_test.cc b/src/common/net/asio_http_test.cc similarity index 99% rename from src/runtime/common/net/asio_http_test.cc rename to src/common/net/asio_http_test.cc index f5da00a4e..da26ae6b9 100644 --- a/src/runtime/common/net/asio_http_test.cc +++ b/src/common/net/asio_http_test.cc @@ -8,7 +8,7 @@ #include "net/asio_tools.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { namespace asio = boost::asio; namespace http = boost::beast::http; @@ -473,4 +473,4 @@ TEST(NET_TEST, Http_server_handle) { t_cli.join(); } -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_tcp_cli.h b/src/common/net/asio_tcp_cli.h similarity index 99% rename from src/runtime/common/net/asio_tcp_cli.h rename to src/common/net/asio_tcp_cli.h index ef6aa9069..0c59d828a 100644 --- a/src/runtime/common/net/asio_tcp_cli.h +++ b/src/common/net/asio_tcp_cli.h @@ -15,7 +15,7 @@ #include "util/log_util.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioTcpClient : public std::enable_shared_from_this { public: @@ -185,7 +185,7 @@ class AsioTcpClient : public std::enable_shared_from_this { try { remote_addr_ = aimrt::common::util::SSToString(session_options_ptr_->svr_ep); - AIMRT_TRACE("Tcp cli session start create a new connect to {}.", RemoteAddr()); + AIMRT_TRACE("Tcp cli session create a new connect to {}.", RemoteAddr()); co_await sock_.async_connect(session_options_ptr_->svr_ep, boost::asio::use_awaitable); @@ -592,4 +592,4 @@ class AsioTcpClientPool std::unordered_map> client_map_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_tcp_svr.h b/src/common/net/asio_tcp_svr.h similarity index 99% rename from src/runtime/common/net/asio_tcp_svr.h rename to src/common/net/asio_tcp_svr.h index 309d0091a..21231ff6b 100644 --- a/src/runtime/common/net/asio_tcp_svr.h +++ b/src/common/net/asio_tcp_svr.h @@ -16,7 +16,7 @@ #include "util/log_util.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioTcpServer : public std::enable_shared_from_this { public: @@ -615,4 +615,4 @@ class AsioTcpServer : public std::enable_shared_from_this { std::unordered_map> session_ptr_map_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_tcp_test.cc b/src/common/net/asio_tcp_test.cc similarity index 97% rename from src/runtime/common/net/asio_tcp_test.cc rename to src/common/net/asio_tcp_test.cc index c197915e5..079a5799c 100644 --- a/src/runtime/common/net/asio_tcp_test.cc +++ b/src/common/net/asio_tcp_test.cc @@ -7,7 +7,7 @@ #include "net/asio_tcp_svr.h" #include "net/asio_tools.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { namespace asio = boost::asio; @@ -95,4 +95,4 @@ TEST(NET_TEST, Tcp_base) { t_cli.join(); } -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_tools.h b/src/common/net/asio_tools.h similarity index 98% rename from src/runtime/common/net/asio_tools.h rename to src/common/net/asio_tools.h index e9b06b023..b9e7ff837 100644 --- a/src/runtime/common/net/asio_tools.h +++ b/src/common/net/asio_tools.h @@ -11,7 +11,7 @@ #include -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { /** * @brief asio执行工具 @@ -185,4 +185,4 @@ class AsioExecutor { std::vector> stop_func_vec_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_udp_cli.h b/src/common/net/asio_udp_cli.h similarity index 99% rename from src/runtime/common/net/asio_udp_cli.h rename to src/common/net/asio_udp_cli.h index 868caba38..5c2f74697 100644 --- a/src/runtime/common/net/asio_udp_cli.h +++ b/src/common/net/asio_udp_cli.h @@ -15,7 +15,7 @@ #include "util/log_util.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioUdpClient : public std::enable_shared_from_this { public: @@ -484,4 +484,4 @@ class AsioUdpClientPool std::unordered_map> client_map_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_udp_svr.h b/src/common/net/asio_udp_svr.h similarity index 99% rename from src/runtime/common/net/asio_udp_svr.h rename to src/common/net/asio_udp_svr.h index c6b0684d6..c3200550d 100644 --- a/src/runtime/common/net/asio_udp_svr.h +++ b/src/common/net/asio_udp_svr.h @@ -17,7 +17,7 @@ #include "util/log_util.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioUdpServer : public std::enable_shared_from_this { public: @@ -423,4 +423,4 @@ class AsioUdpServer : public std::enable_shared_from_this { std::unordered_map> session_ptr_map_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_udp_test.cc b/src/common/net/asio_udp_test.cc similarity index 96% rename from src/runtime/common/net/asio_udp_test.cc rename to src/common/net/asio_udp_test.cc index 752f720a7..86ba8e137 100644 --- a/src/runtime/common/net/asio_udp_test.cc +++ b/src/common/net/asio_udp_test.cc @@ -8,7 +8,7 @@ #include "net/asio_udp_svr.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { namespace asio = boost::asio; @@ -85,4 +85,4 @@ TEST(NET_TEST, UDP_base) { t_cli.join(); } -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_ws_cli.h b/src/common/net/asio_ws_cli.h similarity index 98% rename from src/runtime/common/net/asio_ws_cli.h rename to src/common/net/asio_ws_cli.h index 44e8dc228..339cd77ee 100644 --- a/src/runtime/common/net/asio_ws_cli.h +++ b/src/common/net/asio_ws_cli.h @@ -16,7 +16,7 @@ #include "util/log_util.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioWebSocketClient : public std::enable_shared_from_this { @@ -201,6 +201,10 @@ class AsioWebSocketClient namespace http = boost::beast::http; namespace websocket = boost::beast::websocket; + AIMRT_TRACE("WebSocket cli session create a new connect to {}:{}", + session_options_ptr_->host, + session_options_ptr_->service); + // resolve asio::ip::tcp::resolver resolver(session_socket_strand_); auto const dst = co_await resolver.async_resolve( @@ -593,4 +597,4 @@ class AsioWebSocketClientPool std::unordered_map> client_map_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_ws_svr.h b/src/common/net/asio_ws_svr.h similarity index 99% rename from src/runtime/common/net/asio_ws_svr.h rename to src/common/net/asio_ws_svr.h index 8e101ee4d..f6e4372be 100644 --- a/src/runtime/common/net/asio_ws_svr.h +++ b/src/common/net/asio_ws_svr.h @@ -17,7 +17,7 @@ #include "util/log_util.h" #include "util/string_util.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { class AsioWebSocketServer : public std::enable_shared_from_this { public: @@ -613,4 +613,4 @@ class AsioWebSocketServer : public std::enable_shared_from_this> session_ptr_map_; }; -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/asio_ws_test.cc b/src/common/net/asio_ws_test.cc similarity index 97% rename from src/runtime/common/net/asio_ws_test.cc rename to src/common/net/asio_ws_test.cc index 4319fff5c..2464e52e2 100644 --- a/src/runtime/common/net/asio_ws_test.cc +++ b/src/common/net/asio_ws_test.cc @@ -7,7 +7,7 @@ #include "net/asio_ws_cli.h" #include "net/asio_ws_svr.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { namespace asio = boost::asio; @@ -96,4 +96,4 @@ TEST(NET_TEST, WebSocket_base) { t_svr.join(); } -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/runtime/common/net/http_dispatcher.h b/src/common/net/http_dispatcher.h similarity index 93% rename from src/runtime/common/net/http_dispatcher.h rename to src/common/net/http_dispatcher.h index 11789e667..22f64a07e 100644 --- a/src/runtime/common/net/http_dispatcher.h +++ b/src/common/net/http_dispatcher.h @@ -9,7 +9,7 @@ #include #include -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { /** * @brief http 派发器 @@ -47,4 +47,4 @@ class HttpDispatcher { std::list> http_handle_list_; }; -} // namespace aimrt::runtime::common::net \ No newline at end of file +} // namespace aimrt::common::net \ No newline at end of file diff --git a/src/runtime/common/net/http_dispatcher_test.cc b/src/common/net/http_dispatcher_test.cc similarity index 98% rename from src/runtime/common/net/http_dispatcher_test.cc rename to src/common/net/http_dispatcher_test.cc index 333356d7a..eaf589aeb 100644 --- a/src/runtime/common/net/http_dispatcher_test.cc +++ b/src/common/net/http_dispatcher_test.cc @@ -5,7 +5,7 @@ #include "net/http_dispatcher.h" -namespace aimrt::runtime::common::net { +namespace aimrt::common::net { TEST(HTTP_DISPATCHER_TEST, HttpDispatcher_CASE1) { using TestHttpDispatcher = HttpDispatcher; @@ -220,4 +220,4 @@ TEST(HTTP_DISPATCHER_TEST, HttpDispatcher_CASE3) { } } -} // namespace aimrt::runtime::common::net +} // namespace aimrt::common::net diff --git a/src/common/util/log_util.h b/src/common/util/log_util.h index cf91faf82..0e1c438e0 100644 --- a/src/common/util/log_util.h +++ b/src/common/util/log_util.h @@ -7,7 +7,6 @@ #include #include #include -#include #include "util/block_queue.h" #include "util/exception.h" diff --git a/src/examples/plugins/opentelemetry_plugin/README.md b/src/examples/plugins/opentelemetry_plugin/README.md index 457f62cad..e13525ded 100644 --- a/src/examples/plugins/opentelemetry_plugin/README.md +++ b/src/examples/plugins/opentelemetry_plugin/README.md @@ -17,14 +17,14 @@ 配置文件: -- [examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml](./install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml) +- [examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml](./install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml) 运行方式(linux): - 开启 `AIMRT_BUILD_EXAMPLES`、`AIMRT_BUILD_OPENTELEMETRY_PLUGIN` 选项编译 AimRT; - 将启动配置中的 `trace_otlp_http_exporter_url` 配置为 collector 或 jaejer 的上报地址,详情请参考插件文档; -- 直接运行 build 目录下`start_examples_plugins_opentelemetry_plugin_pb_rpc.sh`脚本启动进程; +- 直接运行 build 目录下`start_examples_plugins_opentelemetry_plugin_pb_rpc_trace.sh`脚本启动进程; - 在 jaejer 平台上观察 rpc trace 数据; - 键入`ctrl-c`停止进程; @@ -52,7 +52,7 @@ 配置文件: -- [examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml](./install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml) +- [examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml](./install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml) @@ -61,7 +61,7 @@ 运行方式(linux): - 开启 `AIMRT_BUILD_EXAMPLES`、`AIMRT_BUILD_OPENTELEMETRY_PLUGIN` 选项编译 AimRT; - 将启动配置中的 `trace_otlp_http_exporter_url` 配置为 collector 或 jaejer 的上报地址,详情请参考插件文档; -- 直接运行 build 目录下`start_examples_plugins_opentelemetry_plugin_pb_chn.sh`脚本启动进程; +- 直接运行 build 目录下`start_examples_plugins_opentelemetry_plugin_pb_chn_trace.sh`脚本启动进程; - 在 jaejer 平台上观察 channel trace 数据; - 键入`ctrl-c`停止进程; @@ -69,3 +69,17 @@ 说明: - 此示例基于 protobuf channel local 后端示例,通过 **opentelemetry_plugin** 中的 `otp_trace` 类型 filter 上报 channel trace 数据; + +## rpc metrics + +一个基于 **opentelemetry_plugin** 的 rpc metrics 示例,演示内容包括: +- 如何在启动时加载 **opentelemetry_plugin**; +- 如何为 rpc 配置 metrics 功能; + + +## channel metrics + +一个基于 **opentelemetry_plugin** 的 channel metrics 示例,演示内容包括: +- 如何在启动时加载 **opentelemetry_plugin**; +- 如何为 channel 配置 metrics 功能; + diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_metrics_cfg.yaml b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_metrics_cfg.yaml new file mode 100644 index 000000000..109ffe0cf --- /dev/null +++ b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_metrics_cfg.yaml @@ -0,0 +1,57 @@ +# Copyright (c) 2023, AgiBot Inc. +# All rights reserved. + +aimrt: + plugin: + plugins: + - name: opentelemetry_plugin + path: ./libaimrt_opentelemetry_plugin.so + options: + node_name: example_channel_node + metrics_otlp_http_exporter_url: http://localhost:4318/v1/metrics + attributes: + - key: sn + val: 123456 + log: + core_lvl: INFO # Trace/Debug/Info/Warn/Error/Fatal/Off + backends: + - type: console + executor: + executors: + - name: work_thread_pool + type: asio_thread + options: + thread_num: 4 + channel: + backends: + - type: local + options: + subscriber_use_inline_executor: false + subscriber_executor: work_thread_pool + pub_topics_options: + - topic_name: "(.*)" + enable_backends: [local] + enable_filters: [otp_metrics] + sub_topics_options: + - topic_name: "(.*)" + enable_backends: [local] + enable_filters: [otp_metrics] + module: + pkgs: + - path: ./libpb_chn_pub_pkg.so + enable_modules: [NormalPublisherModule] + - path: ./libpb_chn_sub_pkg.so + enable_modules: [NormalSubscriberModule] + modules: + - name: NormalPublisherModule + log_lvl: INFO + - name: NormalSubscriberModule + log_lvl: INFO + +# Module custom configuration +NormalPublisherModule: + topic_name: test_topic + channel_frq: 0.5 + +NormalSubscriberModule: + topic_name: test_topic diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml similarity index 100% rename from src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml rename to src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_metrics_cfg.yaml b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_metrics_cfg.yaml new file mode 100644 index 000000000..bebf25867 --- /dev/null +++ b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_metrics_cfg.yaml @@ -0,0 +1,58 @@ +# Copyright (c) 2023, AgiBot Inc. +# All rights reserved. + +aimrt: + plugin: + plugins: + - name: opentelemetry_plugin + path: ./libaimrt_opentelemetry_plugin.so + options: + node_name: example_rpc_node + metrics_otlp_http_exporter_url: http://localhost:4318/v1/metrics + attributes: + - key: sn + val: 123456 + log: + core_lvl: INFO # Trace/Debug/Info/Warn/Error/Fatal/Off + backends: + - type: console + executor: + executors: + - name: work_thread_pool + type: asio_thread + options: + thread_num: 4 + - name: timeout_handle + type: time_wheel + options: + bind_executor: work_thread_pool + rpc: + backends: + - type: local + options: + timeout_executor: timeout_handle + clients_options: + - func_name: "(.*)" + enable_backends: [local] + enable_filters: [otp_metrics] + servers_options: + - func_name: "(.*)" + enable_backends: [local] + enable_filters: [otp_metrics] + module: + pkgs: + - path: ./libpb_rpc_client_pkg.so + enable_modules: [NormalRpcCoClientModule] + - path: ./libpb_rpc_server_pkg.so + enable_modules: [NormalRpcCoServerModule] + modules: + - name: NormalRpcCoClientModule + log_lvl: INFO + - name: NormalRpcCoServerModule + log_lvl: INFO + +# Module custom configuration +NormalRpcCoClientModule: + rpc_frq: 0.5 + +NormalRpcCoServerModule: diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml similarity index 100% rename from src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml rename to src/examples/plugins/opentelemetry_plugin/install/linux/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_metrics.sh b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_metrics.sh new file mode 100755 index 000000000..c68f046da --- /dev/null +++ b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_metrics.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +./aimrt_main --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_chn_metrics_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn.sh b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_trace.sh similarity index 71% rename from src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn.sh rename to src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_trace.sh index 1199c8652..69868b340 100755 --- a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn.sh +++ b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_trace.sh @@ -1,3 +1,3 @@ #!/bin/bash -./aimrt_main --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml +./aimrt_main --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_metrics.sh b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_metrics.sh new file mode 100755 index 000000000..51e7c92f3 --- /dev/null +++ b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_metrics.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +./aimrt_main --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_rpc_metrics_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc.sh b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_trace.sh similarity index 71% rename from src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc.sh rename to src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_trace.sh index 5ed4dc9ee..95410b6b4 100755 --- a/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc.sh +++ b/src/examples/plugins/opentelemetry_plugin/install/linux/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_trace.sh @@ -1,3 +1,3 @@ #!/bin/bash -./aimrt_main --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml +./aimrt_main --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml b/src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml similarity index 100% rename from src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml rename to src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml b/src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml similarity index 100% rename from src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml rename to src/examples/plugins/opentelemetry_plugin/install/win/bin/cfg/examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_chn.bat b/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_trace.bat similarity index 65% rename from src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_chn.bat rename to src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_trace.bat index 7e50dfb01..5fc213aba 100644 --- a/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_chn.bat +++ b/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_chn_trace.bat @@ -1,2 +1,2 @@ -.\aimrt_main.exe --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_chn_cfg.yaml +.\aimrt_main.exe --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_chn_trace_cfg.yaml diff --git a/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc.bat b/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_trace.bat similarity index 65% rename from src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc.bat rename to src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_trace.bat index bf100984f..38a984081 100644 --- a/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc.bat +++ b/src/examples/plugins/opentelemetry_plugin/install/win/bin/start_examples_plugins_opentelemetry_plugin_pb_rpc_trace.bat @@ -1,2 +1,2 @@ -.\aimrt_main.exe --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_rpc_cfg.yaml +.\aimrt_main.exe --cfg_file_path=./cfg/examples_plugins_opentelemetry_plugin_pb_rpc_trace_cfg.yaml diff --git a/src/examples/plugins/ros2_plugin/README.md b/src/examples/plugins/ros2_plugin/README.md index 38850cbb0..1ba5050f4 100644 --- a/src/examples/plugins/ros2_plugin/README.md +++ b/src/examples/plugins/ros2_plugin/README.md @@ -31,12 +31,20 @@ - 开启新的终端运行 build 目录下`start_examples_plugins_ros2_plugin_pb_rpc_client.sh`脚本启动客户端(cli 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - aimrt client 调用 native ros2 server: - - 在终端运行 build 目录下`native_ros2_pb_rpc_server`进程启动原生 ros2 服务端; + - 在 build 目录下运行以下命令启动原生 ros2 服务端: + ```bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_pb_rpc_server + ``` - 开启新的终端运行 build 目录下`start_examples_plugins_ros2_plugin_pb_rpc_client.sh`脚本启动客户端(cli 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - native ros2 client 调用 aimrt server: - 在终端运行 build 目录下`start_examples_plugins_ros2_plugin_pb_rpc_server.sh`脚本启动服务端(srv 进程); - - 开启新的终端运行 build 目录下`native_ros2_pb_rpc_client`进程启动原生 ros2 客户端; + - 开启新的终端,在 build 目录下运行以下命令启动原生 ros2 客户端: + ```bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_pb_rpc_client + ``` - 分别在两个终端键入`ctrl-c`停止对应进程; @@ -82,12 +90,22 @@ - 开启新的终端运行 build 目录下`start_examples_plugins_ros2_plugin_ros2_rpc_client.sh`脚本启动客户端(cli 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - aimrt client 调用 native ros2 server: - - 在终端运行 build 目录下`native_ros2_rpc_server`进程启动原生 ros2 服务端; + - 在 build 目录下运行以下命令启动原生 ros2 服务端: + ```bash + source install/share/example_ros2/local_setup.bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_rpc_server + ``` - 开启新的终端运行 build 目录下`start_examples_plugins_ros2_plugin_ros2_rpc_client.sh`脚本启动客户端(cli 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - native ros2 client 调用 aimrt server: - 在终端运行 build 目录下`start_examples_plugins_ros2_plugin_ros2_rpc_server.sh`脚本启动服务端(srv 进程); - - 开启新的终端运行 build 目录下`native_ros2_rpc_client`进程启动原生 ros2 客户端; + - 开启新的终端,在 build 目录下运行以下命令启动原生 ros2 客户端: + ```bash + source install/share/example_ros2/local_setup.bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_rpc_client + ``` - 分别在两个终端键入`ctrl-c`停止对应进程; @@ -161,12 +179,20 @@ - 再开启一个新的终端窗口运行`start_examples_plugins_ros2_plugin_pb_chn_pub.sh`脚本启动发布端(pub 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - aimrt publisher 向 native ros2 subscriber 发布数据: - - 在终端运行 build 目录下`native_ros2_pb_chn_subscriber`进程启动原生 ros2 订阅端; + - 在 build 目录下运行以下命令启动原生 ros2 订阅端: + ```bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_pb_chn_subscriber + ``` - 再开启一个新的终端窗口运行`start_examples_plugins_ros2_plugin_pb_chn_pub.sh`脚本启动发布端(pub 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - native ros2 publisher 向 aimrt subscriber 发布数据: - 在终端运行 build 目录下`start_examples_plugins_ros_plugin_pb_chn_sub.sh`脚本启动订阅端(sub 进程); - - 开启新的终端运行 build 目录下`native_ros2_pb_chn_publisher`进程启动原生 ros2 发布端; + - 开启新的终端,在 build 目录下运行以下命令启动原生 ros2 发布端: + ```bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_pb_chn_publisher + ``` - 分别在两个终端键入`ctrl-c`停止对应进程; @@ -213,12 +239,22 @@ - 再开启一个新的终端窗口运行`start_examples_plugins_ros2_plugin_ros2_chn_pub.sh`脚本启动发布端(pub 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - aimrt publisher 向 native ros2 subscriber 发布数据: - - 在终端运行 build 目录下`native_ros2_chn_subscriber`进程启动原生 ros2 订阅端; + - 在 build 目录下运行以下命令启动原生 ros2 订阅端: + ```bash + source install/share/example_ros2/local_setup.bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_chn_subscriber + ``` - 再开启一个新的终端窗口运行`start_examples_plugins_ros2_plugin_ros2_chn_pub.sh`脚本启动发布端(pub 进程); - 分别在两个终端键入`ctrl-c`停止对应进程; - native ros2 publisher 向 aimrt subscriber 发布数据: - 在终端运行 build 目录下`start_examples_plugins_ros2_plugin_ros2_chn_sub.sh`脚本启动订阅端(sub 进程); - - 开启新的终端运行 build 目录下`native_ros2_chn_publisher`进程启动原生 ros2 发布端; + - 开启新的终端,在 build 目录下运行以下命令启动原生 ros2 发布端: + ```bash + source install/share/example_ros2/local_setup.bash + source install/share/ros2_plugin_proto/local_setup.bash + native_ros2_chn_publisher + ``` - 分别在两个终端键入`ctrl-c`停止对应进程; diff --git a/src/examples/py/helloworld/examples_py_helloworld_app_mode.py b/src/examples/py/helloworld/examples_py_helloworld_app_mode.py index b3f0f8f96..404d5d971 100644 --- a/src/examples/py/helloworld/examples_py_helloworld_app_mode.py +++ b/src/examples/py/helloworld/examples_py_helloworld_app_mode.py @@ -2,12 +2,13 @@ # All rights reserved. import argparse -import threading import signal import sys +import threading +import time + import aimrt_py import yaml -import time global_aimrt_core = None running_flag = True @@ -73,7 +74,7 @@ def main(): thread_loop = threading.Thread(target=Loop) thread_loop.start() - # wait for shutdown + # Wait for shutdown while thread_start.is_alive(): thread_start.join(1.0) diff --git a/src/examples/py/parameter/README.md b/src/examples/py/parameter/README.md new file mode 100644 index 000000000..c91e716d2 --- /dev/null +++ b/src/examples/py/parameter/README.md @@ -0,0 +1,24 @@ +# parameter example + +一个基于 App 模式创建模块的方式启动的 python parameter 示例,演示内容包括: +- 如何以 App 模式创建模块并启动; +- 如何使用 Log 功能; +- 如何使用 Parameter 功能; + +核心代码: +- [examples_py_parameter_app.py](./examples_py_parameter_app.py) + + +配置文件: +- [examples_py_parameter_app_cfg.yaml](./cfg/examples_py_parameter_app_cfg.yaml) + + +运行方式(linux): +- 安装 `aimrt_py` 包; +- 直接运行本目录下[start_examples_py_parameter_app.sh](./start_examples_py_parameter_app.sh)脚本启动进程; +- 键入`ctrl-c`停止进程; + + +说明: +- 此示例使用 App 模式,在 main 函数中启动 `AimRTCore` 实例,并创建了一个 `ParameterModule` 模块句柄,使用该句柄在两个线程中分别调用 `SetParameter` 和 `GetParameter` 接口,分别进行设置参数和读取参数的操作; +- 可以在启动后观察控制台打印出来的日志,了解框架运行情况; diff --git a/src/examples/py/parameter/cfg/examples_py_parameter_cfg.yaml b/src/examples/py/parameter/cfg/examples_py_parameter_cfg.yaml new file mode 100644 index 000000000..f52e4835a --- /dev/null +++ b/src/examples/py/parameter/cfg/examples_py_parameter_cfg.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2023, AgiBot Inc. +# All rights reserved. + +aimrt: + log: + core_lvl: INFO # Trace/Debug/Info/Warn/Error/Fatal/Off + backends: + - type: console + module: + modules: + - name: ParameterModule + log_lvl: INFO diff --git a/src/examples/py/parameter/examples_py_parameter_app.py b/src/examples/py/parameter/examples_py_parameter_app.py new file mode 100644 index 000000000..f138bf03b --- /dev/null +++ b/src/examples/py/parameter/examples_py_parameter_app.py @@ -0,0 +1,104 @@ +# Copyright (c) 2023, AgiBot Inc. +# All rights reserved. + +import argparse +import signal +import sys +import threading +import time + +import aimrt_py + +global_aimrt_core = None +running_flag = True + + +def signal_handler(sig, _): + global global_aimrt_core + global running_flag + + if (global_aimrt_core and (sig == signal.SIGINT or sig == signal.SIGTERM)): + global_aimrt_core.Shutdown() + running_flag = False + return + + sys.exit(0) + + +def main(): + parser = argparse.ArgumentParser(description='Example parameter app.') + parser.add_argument('--cfg_file_path', type=str, default="", help='config file path') + args = parser.parse_args() + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + print("AimRT start.") + + aimrt_core = aimrt_py.Core() + + global global_aimrt_core + global_aimrt_core = aimrt_core + + core_options = aimrt_py.CoreOptions() + core_options.cfg_file_path = args.cfg_file_path + aimrt_core.Initialize(core_options) + + module_handle = aimrt_core.CreateModule("ParameterModule") + assert (isinstance(module_handle, aimrt_py.CoreRef)) + + parameter_handle = module_handle.GetParameterHandle() + + # Start aimrt core + thread_start = threading.Thread(target=aimrt_core.Start) + thread_start.start() + + time.sleep(1) + + def SetParameterLoop(): + aimrt_py.info(module_handle.GetLogger(), "Start SetParameterLoop.") + count = 0 + global running_flag + while running_flag: + count += 1 + aimrt_py.info(module_handle.GetLogger(), f"SetParameterLoop count: {count} -------------------------") + parameter_handle.SetParameter(f"key-{count}", f"val-{count}") + aimrt_py.info(module_handle.GetLogger(), f"Set parameter, key: 'key-{count}', val: 'val-{count}'") + time.sleep(1) + aimrt_py.info(module_handle.GetLogger(), "SetParameterLoop stopped.") + + def GetParameterLoop(): + aimrt_py.info(module_handle.GetLogger(), "Start GetParameterLoop.") + count = 0 + global running_flag + while running_flag: + count += 1 + aimrt_py.info(module_handle.GetLogger(), f"GetParameterLoop count: {count} -------------------------") + value = parameter_handle.GetParameter(f"key-{count}") + aimrt_py.info(module_handle.GetLogger(), f"Get parameter, key: 'key-{count}', val: '{value}'") + time.sleep(1) + aimrt_py.info(module_handle.GetLogger(), "GetParameterLoop stopped.") + + thread_set_parameter = threading.Thread(target=SetParameterLoop) + thread_get_parameter = threading.Thread(target=GetParameterLoop) + + thread_set_parameter.start() + time.sleep(0.5) + thread_get_parameter.start() + + while thread_start.is_alive(): + thread_start.join(1.0) + + while thread_set_parameter.is_alive(): + thread_set_parameter.join(1.0) + + while thread_get_parameter.is_alive(): + thread_get_parameter.join(1.0) + + global_aimrt_core = None + + print("AimRT exit.") + + +if __name__ == "__main__": + main() diff --git a/src/examples/py/parameter/start_examples_py_parameter.sh b/src/examples/py/parameter/start_examples_py_parameter.sh new file mode 100755 index 000000000..856a62f5c --- /dev/null +++ b/src/examples/py/parameter/start_examples_py_parameter.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +python3 examples_py_parameter_app.py --cfg_file_path ./cfg/examples_py_parameter_cfg.yaml \ No newline at end of file diff --git a/src/examples/py/pb_rpc/examples_py_pb_rpc_server_app.py b/src/examples/py/pb_rpc/examples_py_pb_rpc_server_app.py index 9f5691f50..c01311b32 100644 --- a/src/examples/py/pb_rpc/examples_py_pb_rpc_server_app.py +++ b/src/examples/py/pb_rpc/examples_py_pb_rpc_server_app.py @@ -2,15 +2,14 @@ # All rights reserved. import argparse -import threading import signal import sys +import threading + import aimrt_py - -from google.protobuf.json_format import MessageToJson -import rpc_pb2 import rpc_aimrt_rpc_pb2 - +import rpc_pb2 +from google.protobuf.json_format import MessageToJson global_aimrt_core = None diff --git a/src/examples/py/py_tests.py b/src/examples/py/py_tests.py new file mode 100644 index 000000000..bec505735 --- /dev/null +++ b/src/examples/py/py_tests.py @@ -0,0 +1,350 @@ +import argparse +import os +import signal +import subprocess +import tempfile +import time +from multiprocessing import Process, Queue +from typing import Dict, List, Tuple + + +class TestResult: + SUCCESS = 0 + EXPECTED_OUTPUT_NOT_FOUND = 1 + FORBIDDEN_OUTPUT_FOUND = 2 + EXIT_STRING_NOT_FOUND = 3 + + +def run_program_with_timeout(script_path: str, timeout_seconds: int) -> Tuple[str, str]: + with tempfile.NamedTemporaryFile(mode='w+', suffix='.log', delete=False) as temp_file: + process = subprocess.Popen(script_path, stdout=temp_file, stderr=temp_file, + text=True, shell=True, cwd=os.path.dirname(script_path), + bufsize=1, universal_newlines=True, preexec_fn=os.setsid) + + try: + process.wait(timeout=timeout_seconds) + except subprocess.TimeoutExpired: + # Send SIGTERM signal to the process group + os.killpg(os.getpgid(process.pid), signal.SIGTERM) + # Wait for a short time to allow the process to terminate + time.sleep(1) + if process.poll() is None: + # If the process still hasn't terminated, forcefully terminate it + os.killpg(os.getpgid(process.pid), signal.SIGKILL) + + # Ensure the process has ended + process.wait() + + # Flush the file buffer + temp_file.flush() + os.fsync(temp_file.fileno()) + + # Read the log file content + temp_file.seek(0) + log_content = temp_file.read() + + os.remove(temp_file.name) + + return log_content + + +def run_and_capture(script_path: str, timeout: int, queue: Queue, program_name: str) -> None: + log_content = run_program_with_timeout(script_path, timeout) + queue.put((program_name, log_content)) + + +def check_result(log_content: str, expected_outputs: List[str], forbidden_outputs: List[str]) -> TestResult: + RED = "\033[91m" + RESET = "\033[0m" + + # prepare expected outputs + expected_outputs_lines = [] + for expected_output in expected_outputs: + expected_outputs_lines.extend(expected_output.splitlines()) + + log_lines = log_content.splitlines() + expected_index = 0 + for log_line in log_lines: + if expected_index < len(expected_outputs_lines) and expected_outputs_lines[expected_index] in log_line: + expected_index += 1 + all_expected_found = expected_index == len(expected_outputs_lines) + + if not all_expected_found: + print(f"{RED}Expected outputs not found: {expected_outputs_lines[expected_index:]}{RESET}") + return TestResult.EXPECTED_OUTPUT_NOT_FOUND + + forbidden_found = any(forbidden_output in log_content for forbidden_output in forbidden_outputs) + if forbidden_found: + print(f"{RED}Forbidden output found in log content{RESET}") + return TestResult.FORBIDDEN_OUTPUT_FOUND + + exit_str = "AimRT exit." + exit_found = exit_str in log_content + + if not exit_found: + print(f"{RED}Exit string not found: {exit_str}{RESET}") + return TestResult.EXIT_STRING_NOT_FOUND + + return TestResult.SUCCESS + + +def single_test(script_path: str, + expected_outputs: List[str], + forbidden_outputs: List[str], + timeout: int, + print_output: bool = False) -> TestResult: + start_time = time.perf_counter() + + print("\n" + "=" * 40) + print(f"Running test: {os.path.basename(script_path)}") + + log_content = run_program_with_timeout(script_path, timeout) + + if print_output: + print(log_content) + + end_time = time.perf_counter() + print(f"Total time taken: {end_time - start_time:.2f} seconds") + + result = check_result(log_content, expected_outputs, forbidden_outputs) + + print("=" * 40 + "\n") + + return result + + +def paired_test(server_script: str, + client_script: str, + server_expected_outputs: List[str], + client_expected_outputs: List[str], + server_forbidden_outputs: List[str], + client_forbidden_outputs: List[str], + timeout: int, + print_server_output: bool = False, + print_client_output: bool = False) -> Tuple[TestResult, TestResult]: + start_time = time.perf_counter() + + print("\n" + "=" * 40) + print(f"Running paired test: {os.path.basename(server_script)} and\n" + + f" {os.path.basename(client_script)}") + output_queue = Queue() + + server_process = Process(target=run_and_capture, args=(server_script, timeout, output_queue, "Server")) + client_process = Process(target=run_and_capture, args=(client_script, timeout, output_queue, "Client")) + + server_process.start() + client_process.start() + + server_process.join() + client_process.join() + + end_time = time.perf_counter() + print(f"Total time taken: {end_time - start_time:.2f} seconds") + + while not output_queue.empty(): + program_name, log_content = output_queue.get() + if program_name == "Server": + server_log_content = log_content + if print_server_output: + print(f"\nServer Output:") + print(log_content) + elif program_name == "Client": + client_log_content = log_content + if print_client_output: + print(f"\nClient Output:") + print(log_content) + + server_result = check_result(server_log_content, server_expected_outputs, server_forbidden_outputs) + client_result = check_result(client_log_content, client_expected_outputs, client_forbidden_outputs) + + print("=" * 40 + "\n") + + return server_result, client_result + + +def generate_test_report(test_results: Dict[str, TestResult]) -> str: + # ANSI escape sequences for colors + RESET = "\033[0m" + BOLD = "\033[1m" + RED = "\033[31m" + GREEN = "\033[32m" + YELLOW = "\033[33m" + BLUE = "\033[34m" + MAGENTA = "\033[35m" + CYAN = "\033[36m" + WHITE = "\033[37m" + + total_tests = len(test_results) + successful_tests = sum(1 for result in test_results.values() if result == TestResult.SUCCESS) + not_found_tests = sum(1 for result in test_results.values() if result == TestResult.EXPECTED_OUTPUT_NOT_FOUND) + forbidden_tests = sum(1 for result in test_results.values() if result == TestResult.FORBIDDEN_OUTPUT_FOUND) + exit_failed_tests = sum(1 for result in test_results.values() if result == TestResult.EXIT_STRING_NOT_FOUND) + not_run_tests = sum(1 for result in test_results.values() if result is None) + + report = f""" +{CYAN}{BOLD}╔═══════════════════════════════════════════╗ +║ Test Report Summary ║ +╚═══════════════════════════════════════════╝{RESET} + +{WHITE}Total tests: {CYAN}{total_tests} +{GREEN}Successful tests: {successful_tests} +{RED}Failed tests: {not_found_tests + exit_failed_tests} + {YELLOW}• Expected Output Not Found: {not_found_tests} + {MAGENTA}• Forbidden Output Found: {forbidden_tests} + {RED}• Exit String Not Found: {exit_failed_tests} +{BLUE}Not run tests: {not_run_tests} + +{YELLOW}{BOLD}Detailed Results:{RESET} +""" + for test_name, result in test_results.items(): + if result == TestResult.SUCCESS: + status = f"{GREEN}✔ Success{RESET}" + elif result == TestResult.EXPECTED_OUTPUT_NOT_FOUND: + status = f"{YELLOW}⚠ Expected Output Not Found{RESET}" + elif result == TestResult.FORBIDDEN_OUTPUT_FOUND: + status = f"{MAGENTA}✘ Forbidden Output Found{RESET}" + elif result == TestResult.EXIT_STRING_NOT_FOUND: + status = f"{RED}✘ Exit String Not Found{RESET}" + else: # result is None + status = f"{BLUE}- Not Run{RESET}" + report += f" {CYAN}•{RESET} {test_name:<20} {status}\n" + + success_rate = (successful_tests / (total_tests - not_run_tests)) * 100 if (total_tests - not_run_tests) > 0 else 0 + overall_success_rate = (successful_tests / total_tests) * 100 if total_tests > 0 else 0 + report += f"\n{YELLOW}Success Rate (excluding not run): {WHITE}{success_rate:.2f}%{RESET}" + report += f"\n{YELLOW}Overall Success Rate: {WHITE}{overall_success_rate:.2f}%{RESET}" + + return report + + +def parse_args(): + parser = argparse.ArgumentParser(description="Run Python tests") + parser.add_argument("-p", "--print-output", action="store_true", help="Print test output", default=False) + parser.add_argument("-t", "--test", type=str, help="Test name", default="all") + args = parser.parse_args() + return args + + +if __name__ == "__main__": + args = parse_args() + try: + test_results = {"app mode": None, "registration mode": None, + "http rpc server": None, "http rpc client": None, + "grpc rpc server": None, "grpc rpc client": None, + "ros2 rpc server": None, "ros2 rpc client": None, + "http channel sub": None, "http channel pub": None, + "ros2 channel sub": None, "ros2 channel pub": None, + "parameter": None} + + common_forbidden_outputs = ["[Error]", "[Fatal]", "Traceback (most recent call last):"] + + # build pb_rpc and pb_chn + if args.test in ["all", "rpc"] or "rpc" in args.test: + subprocess.run(["bash", os.path.join(os.getcwd(), "pb_rpc", "build_examples_py_pb_rpc.sh")], + cwd=os.path.join(os.getcwd(), "pb_rpc")) + if args.test in ["all", "channel"] or "channel" in args.test: + subprocess.run(["bash", os.path.join(os.getcwd(), "pb_chn", "build_examples_py_pb_chn.sh")], + cwd=os.path.join(os.getcwd(), "pb_chn")) + + if args.test in ["all", "app mode", "helloworld"]: + test_results["app mode"] = single_test( + os.path.join(os.getcwd(), "helloworld", "start_examples_py_helloworld_app_mode.sh"), + expected_outputs=["{'key1': 'val1', 'key2': 'val2'}", "Loop count: 1", "Loop count: 2"], + forbidden_outputs=common_forbidden_outputs, + timeout=3, + print_output=args.print_output) + + if args.test in ["all", "registration mode", "helloworld"]: + test_results["registration mode"] = single_test( + os.path.join(os.getcwd(), "helloworld", "start_examples_py_helloworld_registration_mode.sh"), + expected_outputs=["{'key1': 'val1', 'key2': 'val2'}"] + ["run test task"] * 3, + forbidden_outputs=common_forbidden_outputs, + timeout=2, + print_output=args.print_output) + + rpc_server_expected_outputs = ["Server handle new rpc call."] + rpc_client_expected_outputs = ["Call rpc done, status: suc, code 0, msg: OK"] + + if args.test in ["all", "rpc", "http rpc"]: + test_results["http rpc server"], test_results["http rpc client"] = paired_test( + os.path.join(os.getcwd(), "pb_rpc", "start_examples_py_pb_rpc_http_server.sh"), + os.path.join(os.getcwd(), "pb_rpc", "start_examples_py_pb_rpc_http_client.sh"), + server_expected_outputs=rpc_server_expected_outputs, + client_expected_outputs=rpc_client_expected_outputs, + server_forbidden_outputs=common_forbidden_outputs, + client_forbidden_outputs=common_forbidden_outputs, + timeout=2, + print_server_output=args.print_output, + print_client_output=args.print_output) + + if args.test in ["all", "rpc", "grpc rpc"]: + test_results["grpc rpc server"], test_results["grpc rpc client"] = paired_test( + os.path.join(os.getcwd(), "pb_rpc", "start_examples_py_pb_rpc_grpc_server.sh"), + os.path.join(os.getcwd(), "pb_rpc", "start_examples_py_pb_rpc_grpc_client.sh"), + server_expected_outputs=rpc_server_expected_outputs, + client_expected_outputs=rpc_client_expected_outputs, + server_forbidden_outputs=common_forbidden_outputs, + client_forbidden_outputs=common_forbidden_outputs, + timeout=2, + print_server_output=args.print_output, + print_client_output=args.print_output) + + if args.test in ["all", "rpc", "ros2 rpc"]: + test_results["ros2 rpc server"], test_results["ros2 rpc client"] = paired_test( + os.path.join(os.getcwd(), "pb_rpc", "start_examples_py_pb_rpc_ros2_server.sh"), + os.path.join(os.getcwd(), "pb_rpc", "start_examples_py_pb_rpc_ros2_client.sh"), + server_expected_outputs=rpc_server_expected_outputs, + client_expected_outputs=rpc_client_expected_outputs, + server_forbidden_outputs=common_forbidden_outputs, + client_forbidden_outputs=common_forbidden_outputs, + timeout=2, + print_server_output=args.print_output, + print_client_output=args.print_output) + + channel_sub_expected_outputs = ["Get new pb event, data: {", "\"msg\": \"example msg\"", "\"num\": 123456"] + channel_pub_expected_outputs = ["Publish new pb event, data: {", "\"msg\": \"example msg\"", "\"num\": 123456"] + + if args.test in ["all", "channel", "http channel"]: + test_results["http channel sub"], test_results["http channel pub"] = paired_test( + os.path.join(os.getcwd(), "pb_chn", "start_examples_py_pb_chn_http_sub.sh"), + os.path.join(os.getcwd(), "pb_chn", "start_examples_py_pb_chn_http_pub.sh"), + server_expected_outputs=channel_sub_expected_outputs, + client_expected_outputs=channel_pub_expected_outputs, + server_forbidden_outputs=common_forbidden_outputs, + client_forbidden_outputs=common_forbidden_outputs, + timeout=3, + print_server_output=args.print_output, + print_client_output=args.print_output) + + if args.test in ["all", "channel", "ros2 channel"]: + test_results["ros2 channel sub"], test_results["ros2 channel pub"] = paired_test( + os.path.join(os.getcwd(), "pb_chn", "start_examples_py_pb_chn_ros2_sub.sh"), + os.path.join(os.getcwd(), "pb_chn", "start_examples_py_pb_chn_ros2_pub.sh"), + server_expected_outputs=channel_sub_expected_outputs, + client_expected_outputs=channel_pub_expected_outputs, + server_forbidden_outputs=common_forbidden_outputs, + client_forbidden_outputs=common_forbidden_outputs, + timeout=3, + print_server_output=args.print_output, + print_client_output=args.print_output) + + if args.test in ["all", "parameter"]: + test_results["parameter"] = single_test( + os.path.join(os.getcwd(), "parameter", "start_examples_py_parameter.sh"), + expected_outputs=["Start SetParameterLoop.", + "SetParameterLoop count: 1 -------------------------", + "Set parameter, key: 'key-1', val: 'val-1'", + "Start GetParameterLoop.", + "GetParameterLoop count: 1 -------------------------", + "Get parameter, key: 'key-1', val: 'val-1'"], + forbidden_outputs=common_forbidden_outputs, + timeout=3, + print_output=args.print_output) + + except KeyboardInterrupt: + print("\nTests interrupted by user") + except Exception as e: + print(f"An unexpected error occurred: {e}") + finally: + report = generate_test_report(test_results) + print(report) diff --git a/src/plugins/grpc_plugin/CMakeLists.txt b/src/plugins/grpc_plugin/CMakeLists.txt index 0ce9b535f..e7ac8f12e 100644 --- a/src/plugins/grpc_plugin/CMakeLists.txt +++ b/src/plugins/grpc_plugin/CMakeLists.txt @@ -34,7 +34,7 @@ target_link_libraries( ${CUR_TARGET_NAME} PRIVATE aimrt::interface::aimrt_core_plugin_interface aimrt::runtime::core - aimrt::runtime::common::net + aimrt::common::net nghttp2::nghttp2) # Add -Werror option diff --git a/src/plugins/grpc_plugin/client/connection.h b/src/plugins/grpc_plugin/client/connection.h index b872af65c..83dc2ab2b 100644 --- a/src/plugins/grpc_plugin/client/connection.h +++ b/src/plugins/grpc_plugin/client/connection.h @@ -43,7 +43,7 @@ using HttpHandleType = Awaitable(const RequestPtr&, ResponsePtr&); using HttpHandle = std::function; -namespace net = aimrt::runtime::common::net; +namespace net = aimrt::common::net; using Dispatcher = net::HttpDispatcher; namespace chrono = std::chrono; diff --git a/src/plugins/grpc_plugin/grpc_plugin.cc b/src/plugins/grpc_plugin/grpc_plugin.cc index 351b8c7f8..6e96353d1 100644 --- a/src/plugins/grpc_plugin/grpc_plugin.cc +++ b/src/plugins/grpc_plugin/grpc_plugin.cc @@ -78,7 +78,7 @@ bool GrpcPlugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { init_flag_ = true; - asio_executor_ptr_ = std::make_shared(options_.thread_num); + asio_executor_ptr_ = std::make_shared(options_.thread_num); core_ptr_->RegisterHookFunc(runtime::core::AimRTCore::State::kPostInitLog, [this] { SetPluginLogger(); }); diff --git a/src/plugins/grpc_plugin/grpc_plugin.h b/src/plugins/grpc_plugin/grpc_plugin.h index 302c649f4..97ade8c3f 100644 --- a/src/plugins/grpc_plugin/grpc_plugin.h +++ b/src/plugins/grpc_plugin/grpc_plugin.h @@ -42,7 +42,7 @@ class GrpcPlugin : public AimRTCorePluginBase { bool init_flag_ = false; - std::shared_ptr asio_executor_ptr_; + std::shared_ptr asio_executor_ptr_; std::shared_ptr http2_svr_ptr_; std::shared_ptr http2_cli_pool_ptr_; diff --git a/src/plugins/grpc_plugin/server/connection.h b/src/plugins/grpc_plugin/server/connection.h index 60f0d17f7..0904df546 100644 --- a/src/plugins/grpc_plugin/server/connection.h +++ b/src/plugins/grpc_plugin/server/connection.h @@ -35,7 +35,7 @@ using ResponsePtr = std::shared_ptr; using HttpHandle = std::function(const RequestPtr&, ResponsePtr&)>; -namespace net = aimrt::runtime::common::net; +namespace net = aimrt::common::net; using Dispatcher = net::HttpDispatcher(const RequestPtr&, ResponsePtr&)>; namespace asio = boost::asio; diff --git a/src/plugins/net_plugin/CMakeLists.txt b/src/plugins/net_plugin/CMakeLists.txt index 5aeb081d9..bad24188a 100644 --- a/src/plugins/net_plugin/CMakeLists.txt +++ b/src/plugins/net_plugin/CMakeLists.txt @@ -33,12 +33,8 @@ target_include_directories( target_link_libraries( ${CUR_TARGET_NAME} PRIVATE aimrt::interface::aimrt_core_plugin_interface - aimrt::runtime::common::net - aimrt::runtime::core - Boost::beast) - -# Set compile definitions of target -target_compile_definitions(${CUR_TARGET_NAME} INTERFACE BOOST_ASIO_NO_DEPRECATED) + aimrt::common::net + aimrt::runtime::core) # Set compile options of target if(WIN32) diff --git a/src/plugins/net_plugin/http/http_channel_backend.cc b/src/plugins/net_plugin/http/http_channel_backend.cc index a6c634697..b574b544e 100644 --- a/src/plugins/net_plugin/http/http_channel_backend.cc +++ b/src/plugins/net_plugin/http/http_channel_backend.cc @@ -165,12 +165,12 @@ bool HttpChannelBackend::Subscribe( http_subscribe_wrapper_map_.emplace(pattern, std::move(sub_tool_unique_ptr)); - runtime::common::net::AsioHttpServer::HttpHandle http_handle = + aimrt::common::net::AsioHttpServer::HttpHandle http_handle = [this, topic_name = info.topic_name, sub_tool_ptr]( const http::request& req, http::response& rsp, std::chrono::nanoseconds timeout) - -> asio::awaitable { + -> asio::awaitable { // 获取序列化类型 std::string serialization_type; auto req_content_type_itr = req.find(http::field::content_type); @@ -224,7 +224,7 @@ bool HttpChannelBackend::Subscribe( sub_tool_ptr->DoSubscribeCallback(ctx_ptr, serialization_type, buffer_array_view); - co_return runtime::common::net::AsioHttpServer::HttpHandleStatus::kOk; + co_return aimrt::common::net::AsioHttpServer::HttpHandleStatus::kOk; }; http_svr_ptr_->RegisterHttpHandleFunc( @@ -337,7 +337,7 @@ void HttpChannelBackend::Publish(runtime::core::channel::MsgWrapper& msg_wrapper asio::co_spawn( *io_ptr_, [this, server_url, req_ptr]() -> asio::awaitable { - runtime::common::net::AsioHttpClient::Options cli_options{ + aimrt::common::net::AsioHttpClient::Options cli_options{ .host = server_url.host, .service = server_url.service}; diff --git a/src/plugins/net_plugin/http/http_channel_backend.h b/src/plugins/net_plugin/http/http_channel_backend.h index 3314d435a..260dd4103 100644 --- a/src/plugins/net_plugin/http/http_channel_backend.h +++ b/src/plugins/net_plugin/http/http_channel_backend.h @@ -32,8 +32,8 @@ class HttpChannelBackend : public runtime::core::channel::ChannelBackendBase { public: HttpChannelBackend( const std::shared_ptr& io_ptr, - const std::shared_ptr& http_cli_pool_ptr, - const std::shared_ptr& http_svr_ptr) + const std::shared_ptr& http_cli_pool_ptr, + const std::shared_ptr& http_svr_ptr) : io_ptr_(io_ptr), http_cli_pool_ptr_(http_cli_pool_ptr), http_svr_ptr_(http_svr_ptr) {} @@ -69,8 +69,8 @@ class HttpChannelBackend : public runtime::core::channel::ChannelBackendBase { const runtime::core::channel::ChannelRegistry* channel_registry_ptr_ = nullptr; std::shared_ptr io_ptr_; - std::shared_ptr http_cli_pool_ptr_; - std::shared_ptr http_svr_ptr_; + std::shared_ptr http_cli_pool_ptr_; + std::shared_ptr http_svr_ptr_; std::unordered_map< std::string, diff --git a/src/plugins/net_plugin/http/http_rpc_backend.cc b/src/plugins/net_plugin/http/http_rpc_backend.cc index e55a26119..aadefe74f 100644 --- a/src/plugins/net_plugin/http/http_rpc_backend.cc +++ b/src/plugins/net_plugin/http/http_rpc_backend.cc @@ -104,12 +104,12 @@ bool HttpRpcBackend::RegisterServiceFunc( std::string pattern = std::string("/rpc") + std::string(GetRealFuncName(service_func_wrapper.info.func_name)); - runtime::common::net::AsioHttpServer::HttpHandle http_handle = + aimrt::common::net::AsioHttpServer::HttpHandle http_handle = [this, &service_func_wrapper]( const http::request& req, http::response& rsp, std::chrono::nanoseconds timeout) - -> asio::awaitable { + -> asio::awaitable { // 创建 service invoke wrapper auto service_invoke_wrapper_ptr = std::make_shared( runtime::core::rpc::InvokeWrapper{.info = service_func_wrapper.info}); @@ -258,7 +258,7 @@ bool HttpRpcBackend::RegisterServiceFunc( AIMRT_CHECK_ERROR_THROW(ret_code == 0, "Handle rpc failed, code: {}.", ret_code); - co_return runtime::common::net::AsioHttpServer::HttpHandleStatus::kOk; + co_return aimrt::common::net::AsioHttpServer::HttpHandleStatus::kOk; }; http_svr_ptr_->RegisterHttpHandleFunc( @@ -354,7 +354,7 @@ void HttpRpcBackend::Invoke( } try { - runtime::common::net::AsioHttpClient::Options cli_options{ + aimrt::common::net::AsioHttpClient::Options cli_options{ .host = std::string(url->host), .service = std::string(url->service)}; diff --git a/src/plugins/net_plugin/http/http_rpc_backend.h b/src/plugins/net_plugin/http/http_rpc_backend.h index 1251e0094..463e20cd6 100644 --- a/src/plugins/net_plugin/http/http_rpc_backend.h +++ b/src/plugins/net_plugin/http/http_rpc_backend.h @@ -27,8 +27,8 @@ class HttpRpcBackend : public runtime::core::rpc::RpcBackendBase { public: HttpRpcBackend( const std::shared_ptr& io_ptr, - const std::shared_ptr& http_cli_pool_ptr, - const std::shared_ptr& http_svr_ptr) + const std::shared_ptr& http_cli_pool_ptr, + const std::shared_ptr& http_svr_ptr) : io_ptr_(io_ptr), http_cli_pool_ptr_(http_cli_pool_ptr), http_svr_ptr_(http_svr_ptr) {} @@ -75,8 +75,8 @@ class HttpRpcBackend : public runtime::core::rpc::RpcBackendBase { std::unordered_map client_server_url_map_; std::shared_ptr io_ptr_; - std::shared_ptr http_cli_pool_ptr_; - std::shared_ptr http_svr_ptr_; + std::shared_ptr http_cli_pool_ptr_; + std::shared_ptr http_svr_ptr_; }; } // namespace aimrt::plugins::net_plugin \ No newline at end of file diff --git a/src/plugins/net_plugin/net_plugin.cc b/src/plugins/net_plugin/net_plugin.cc index 39ead5d57..a13e740d7 100644 --- a/src/plugins/net_plugin/net_plugin.cc +++ b/src/plugins/net_plugin/net_plugin.cc @@ -109,15 +109,15 @@ bool NetPlugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { init_flag_ = true; - asio_executor_ptr_ = std::make_shared(options_.thread_num); + asio_executor_ptr_ = std::make_shared(options_.thread_num); core_ptr_->RegisterHookFunc(runtime::core::AimRTCore::State::kPostInitLog, [this] { SetPluginLogger(); }); // http if (options_.http_options) { - http_cli_pool_ptr_ = std::make_shared(asio_executor_ptr_->IO()); - http_svr_ptr_ = std::make_shared(asio_executor_ptr_->IO()); + http_cli_pool_ptr_ = std::make_shared(asio_executor_ptr_->IO()); + http_svr_ptr_ = std::make_shared(asio_executor_ptr_->IO()); core_ptr_->RegisterHookFunc(runtime::core::AimRTCore::State::kPreInitRpc, [this] { RegisterHttpRpcBackend(); }); @@ -129,11 +129,11 @@ bool NetPlugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { runtime::core::AimRTCore::State::kPreStart, [this] { http_cli_pool_ptr_->SetLogger(WrapAimRTLoggerRef(GetLogger())); - http_cli_pool_ptr_->Initialize(runtime::common::net::AsioHttpClientPool::Options{}); + http_cli_pool_ptr_->Initialize(aimrt::common::net::AsioHttpClientPool::Options{}); http_cli_pool_ptr_->Start(); http_svr_ptr_->SetLogger(WrapAimRTLoggerRef(GetLogger())); - http_svr_ptr_->Initialize(runtime::common::net::AsioHttpServer::Options{ + http_svr_ptr_->Initialize(aimrt::common::net::AsioHttpServer::Options{ .ep = {boost::asio::ip::make_address_v4(options_.http_options->listen_ip), options_.http_options->listen_port}}); http_svr_ptr_->Start(); @@ -149,9 +149,9 @@ bool NetPlugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { // tcp if (options_.tcp_options) { - tcp_cli_pool_ptr_ = std::make_shared(asio_executor_ptr_->IO()); + tcp_cli_pool_ptr_ = std::make_shared(asio_executor_ptr_->IO()); tcp_msg_handle_registry_ptr_ = std::make_shared>(); - tcp_svr_ptr_ = std::make_shared(asio_executor_ptr_->IO()); + tcp_svr_ptr_ = std::make_shared(asio_executor_ptr_->IO()); core_ptr_->RegisterHookFunc(runtime::core::AimRTCore::State::kPreInitChannel, [this] { RegisterTcpChannelBackend(); }); @@ -160,12 +160,12 @@ bool NetPlugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { runtime::core::AimRTCore::State::kPreStart, [this] { tcp_cli_pool_ptr_->SetLogger(WrapAimRTLoggerRef(GetLogger())); - tcp_cli_pool_ptr_->Initialize(runtime::common::net::AsioTcpClientPool::Options{}); + tcp_cli_pool_ptr_->Initialize(aimrt::common::net::AsioTcpClientPool::Options{}); tcp_cli_pool_ptr_->Start(); tcp_svr_ptr_->SetLogger(WrapAimRTLoggerRef(GetLogger())); tcp_svr_ptr_->RegisterMsgHandle(tcp_msg_handle_registry_ptr_->GetMsgHandleFunc()); - tcp_svr_ptr_->Initialize(runtime::common::net::AsioTcpServer::Options{ + tcp_svr_ptr_->Initialize(aimrt::common::net::AsioTcpServer::Options{ .ep = {boost::asio::ip::make_address_v4(options_.tcp_options->listen_ip), options_.tcp_options->listen_port}}); tcp_svr_ptr_->Start(); @@ -181,9 +181,9 @@ bool NetPlugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { // udp if (options_.udp_options) { - udp_cli_pool_ptr_ = std::make_shared(asio_executor_ptr_->IO()); + udp_cli_pool_ptr_ = std::make_shared(asio_executor_ptr_->IO()); udp_msg_handle_registry_ptr_ = std::make_shared>(); - udp_svr_ptr_ = std::make_shared(asio_executor_ptr_->IO()); + udp_svr_ptr_ = std::make_shared(asio_executor_ptr_->IO()); core_ptr_->RegisterHookFunc(runtime::core::AimRTCore::State::kPreInitChannel, [this] { RegisterUdpChannelBackend(); }); @@ -192,12 +192,12 @@ bool NetPlugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { runtime::core::AimRTCore::State::kPreStart, [this] { udp_cli_pool_ptr_->SetLogger(WrapAimRTLoggerRef(GetLogger())); - udp_cli_pool_ptr_->Initialize(runtime::common::net::AsioUdpClientPool::Options{}); + udp_cli_pool_ptr_->Initialize(aimrt::common::net::AsioUdpClientPool::Options{}); udp_cli_pool_ptr_->Start(); udp_svr_ptr_->SetLogger(WrapAimRTLoggerRef(GetLogger())); udp_svr_ptr_->RegisterMsgHandle(udp_msg_handle_registry_ptr_->GetMsgHandleFunc()); - udp_svr_ptr_->Initialize(runtime::common::net::AsioUdpServer::Options{ + udp_svr_ptr_->Initialize(aimrt::common::net::AsioUdpServer::Options{ .ep = {boost::asio::ip::make_address_v4(options_.udp_options->listen_ip), options_.udp_options->listen_port}, .max_package_size = options_.udp_options->max_pkg_size}); diff --git a/src/plugins/net_plugin/net_plugin.h b/src/plugins/net_plugin/net_plugin.h index 89d010ab0..f60e3bc4b 100644 --- a/src/plugins/net_plugin/net_plugin.h +++ b/src/plugins/net_plugin/net_plugin.h @@ -67,18 +67,18 @@ class NetPlugin : public AimRTCorePluginBase { bool init_flag_ = false; - std::shared_ptr asio_executor_ptr_; + std::shared_ptr asio_executor_ptr_; - std::shared_ptr http_cli_pool_ptr_; - std::shared_ptr http_svr_ptr_; + std::shared_ptr http_cli_pool_ptr_; + std::shared_ptr http_svr_ptr_; - std::shared_ptr tcp_cli_pool_ptr_; + std::shared_ptr tcp_cli_pool_ptr_; std::shared_ptr> tcp_msg_handle_registry_ptr_; - std::shared_ptr tcp_svr_ptr_; + std::shared_ptr tcp_svr_ptr_; - std::shared_ptr udp_cli_pool_ptr_; + std::shared_ptr udp_cli_pool_ptr_; std::shared_ptr> udp_msg_handle_registry_ptr_; - std::shared_ptr udp_svr_ptr_; + std::shared_ptr udp_svr_ptr_; }; } // namespace aimrt::plugins::net_plugin diff --git a/src/plugins/net_plugin/tcp/tcp_channel_backend.cc b/src/plugins/net_plugin/tcp/tcp_channel_backend.cc index 4c614e162..f12dd3dff 100644 --- a/src/plugins/net_plugin/tcp/tcp_channel_backend.cc +++ b/src/plugins/net_plugin/tcp/tcp_channel_backend.cc @@ -289,7 +289,7 @@ void TcpChannelBackend::Publish(runtime::core::channel::MsgWrapper& msg_wrapper) boost::asio::co_spawn( *io_ptr_, [this, server_ep, msg_buf_ptr]() -> boost::asio::awaitable { - runtime::common::net::AsioTcpClient::Options client_options{ + aimrt::common::net::AsioTcpClient::Options client_options{ .svr_ep = server_ep}; auto cli = co_await tcp_cli_pool_ptr_->GetClient(client_options); diff --git a/src/plugins/net_plugin/tcp/tcp_channel_backend.h b/src/plugins/net_plugin/tcp/tcp_channel_backend.h index aa8aa986d..1c0b42946 100644 --- a/src/plugins/net_plugin/tcp/tcp_channel_backend.h +++ b/src/plugins/net_plugin/tcp/tcp_channel_backend.h @@ -29,8 +29,8 @@ class TcpChannelBackend : public runtime::core::channel::ChannelBackendBase { public: TcpChannelBackend( const std::shared_ptr& io_ptr, - const std::shared_ptr& tcp_cli_pool_ptr, - const std::shared_ptr& tcp_svr_ptr, + const std::shared_ptr& tcp_cli_pool_ptr, + const std::shared_ptr& tcp_svr_ptr, const std::shared_ptr& msg_handle_registry_ptr) : io_ptr_(io_ptr), tcp_cli_pool_ptr_(tcp_cli_pool_ptr), @@ -68,9 +68,9 @@ class TcpChannelBackend : public runtime::core::channel::ChannelBackendBase { const runtime::core::channel::ChannelRegistry* channel_registry_ptr_ = nullptr; std::shared_ptr io_ptr_; - std::shared_ptr tcp_cli_pool_ptr_; + std::shared_ptr tcp_cli_pool_ptr_; std::shared_ptr msg_handle_registry_ptr_; - std::shared_ptr tcp_svr_ptr_; + std::shared_ptr tcp_svr_ptr_; std::unordered_map< std::string, diff --git a/src/plugins/net_plugin/udp/udp_channel_backend.cc b/src/plugins/net_plugin/udp/udp_channel_backend.cc index ae0d57058..24186a940 100644 --- a/src/plugins/net_plugin/udp/udp_channel_backend.cc +++ b/src/plugins/net_plugin/udp/udp_channel_backend.cc @@ -286,7 +286,7 @@ void UdpChannelBackend::Publish(runtime::core::channel::MsgWrapper& msg_wrapper) boost::asio::co_spawn( *io_ptr_, [this, server_ep, msg_buf_ptr]() -> boost::asio::awaitable { - runtime::common::net::AsioUdpClient::Options client_options{ + aimrt::common::net::AsioUdpClient::Options client_options{ .svr_ep = server_ep}; auto cli = co_await udp_cli_pool_ptr_->GetClient(client_options); diff --git a/src/plugins/net_plugin/udp/udp_channel_backend.h b/src/plugins/net_plugin/udp/udp_channel_backend.h index 5bc8b90ac..ff14da1e1 100644 --- a/src/plugins/net_plugin/udp/udp_channel_backend.h +++ b/src/plugins/net_plugin/udp/udp_channel_backend.h @@ -29,8 +29,8 @@ class UdpChannelBackend : public runtime::core::channel::ChannelBackendBase { public: UdpChannelBackend( const std::shared_ptr& io_ptr, - const std::shared_ptr& udp_cli_pool_ptr, - const std::shared_ptr& udp_svr_ptr, + const std::shared_ptr& udp_cli_pool_ptr, + const std::shared_ptr& udp_svr_ptr, const std::shared_ptr& msg_handle_registry_ptr) : io_ptr_(io_ptr), udp_cli_pool_ptr_(udp_cli_pool_ptr), @@ -68,9 +68,9 @@ class UdpChannelBackend : public runtime::core::channel::ChannelBackendBase { const runtime::core::channel::ChannelRegistry* channel_registry_ptr_ = nullptr; std::shared_ptr io_ptr_; - std::shared_ptr udp_cli_pool_ptr_; + std::shared_ptr udp_cli_pool_ptr_; std::shared_ptr msg_handle_registry_ptr_; - std::shared_ptr udp_svr_ptr_; + std::shared_ptr udp_svr_ptr_; std::unordered_map< std::string, diff --git a/src/plugins/opentelemetry_plugin/context_carrier.h b/src/plugins/opentelemetry_plugin/context_carrier.h index 6540a0a36..b91183515 100644 --- a/src/plugins/opentelemetry_plugin/context_carrier.h +++ b/src/plugins/opentelemetry_plugin/context_carrier.h @@ -16,16 +16,14 @@ class ContextCarrier : public opentelemetry::context::propagation::TextMapCarrie : ctx_ref_(ctx_ref) {} ContextCarrier() = default; - virtual opentelemetry::nostd::string_view Get( - opentelemetry::nostd::string_view key) const noexcept override { + virtual std::string_view Get(std::string_view key) const noexcept override { std::string real_key = std::string(kCtxKeyPrefix) + std::string(key); - return ToNoStdStringView(ctx_ref_.GetMetaValue(real_key)); + return ctx_ref_.GetMetaValue(real_key); } - virtual void Set(opentelemetry::nostd::string_view key, - opentelemetry::nostd::string_view value) noexcept override { + virtual void Set(std::string_view key, std::string_view value) noexcept override { std::string real_key = std::string(kCtxKeyPrefix) + std::string(key); - ctx_ref_.SetMetaValue(real_key, ToStdStringView(value)); + ctx_ref_.SetMetaValue(real_key, value); } ContetxRefType ctx_ref_; diff --git a/src/plugins/opentelemetry_plugin/opentelemetry_plugin.cc b/src/plugins/opentelemetry_plugin/opentelemetry_plugin.cc index 507637860..9be22e11f 100644 --- a/src/plugins/opentelemetry_plugin/opentelemetry_plugin.cc +++ b/src/plugins/opentelemetry_plugin/opentelemetry_plugin.cc @@ -19,9 +19,14 @@ struct convert(); - rhs.trace_otlp_http_exporter_url = node["trace_otlp_http_exporter_url"].as(); + + if (node["trace_otlp_http_exporter_url"]) + rhs.trace_otlp_http_exporter_url = node["trace_otlp_http_exporter_url"].as(); if (node["force_trace"]) rhs.force_trace = node["force_trace"].as(); + if (node["metrics_otlp_http_exporter_url"]) + rhs.metrics_otlp_http_exporter_url = node["metrics_otlp_http_exporter_url"].as(); + + if (node["metrics_export_interval_ms"]) + rhs.metrics_export_interval_ms = node["metrics_export_interval_ms"].as(); + + if (node["metrics_export_timeout_ms"]) + rhs.metrics_export_timeout_ms = node["metrics_export_timeout_ms"].as(); + for (const auto& attribute_node : node["attributes"]) { auto attribute = Options::Attribute{ .key = attribute_node["key"].as(), @@ -57,6 +73,8 @@ struct convert(); + // trace + if (!options_.trace_otlp_http_exporter_url.empty()) { + enable_trace_ = true; + + otlp::OtlpHttpExporterOptions opts; + opts.url = options_.trace_otlp_http_exporter_url; + auto exporter = otlp::OtlpHttpExporterFactory::Create(opts); + + trace_sdk::BatchSpanProcessorOptions bsp_opts{}; + auto processor = trace_sdk::BatchSpanProcessorFactory::Create(std::move(exporter), bsp_opts); + + trace_provider_ = trace_sdk::TracerProviderFactory::Create(std::move(processor), resource); + + tracer_ = trace_provider_->GetTracer(options_.node_name); + } + + // metrics + if (!options_.metrics_otlp_http_exporter_url.empty()) { + enable_metrics_ = true; + + otlp::OtlpHttpMetricExporterOptions opts; + opts.url = options_.metrics_otlp_http_exporter_url; + auto exporter = otlp::OtlpHttpMetricExporterFactory::Create(opts); + + metric_sdk::PeriodicExportingMetricReaderOptions reader_opts{}; + reader_opts.export_interval_millis = std::chrono::milliseconds(options_.metrics_export_interval_ms); + reader_opts.export_timeout_millis = std::chrono::milliseconds(options_.metrics_export_timeout_ms); + + auto reader = + metric_sdk::PeriodicExportingMetricReaderFactory::Create(std::move(exporter), reader_opts); + + auto views = metric_sdk::ViewRegistryFactory::Create(); + + auto context = metric_sdk::MeterContextFactory::Create(std::move(views), resource); + context->AddMetricReader(std::move(reader)); + + meter_provider_ = metric_sdk::MeterProviderFactory::Create(std::move(context)); + + meter_ = meter_provider_->GetMeter(options_.node_name); + + chn_pub_msg_num_counter_ = meter_->CreateUInt64Counter("chn.pub.msg_num", "Total num of channel publish msg"); + chn_sub_msg_num_counter_ = meter_->CreateUInt64Counter("chn.sub.msg_num", "Total num of channel subscribe msg"); + + chn_pub_msg_size_counter_ = meter_->CreateUInt64Counter("chn.pub.msg_size", "Total size of channel publish msg", "bytes"); + chn_sub_msg_size_counter_ = meter_->CreateUInt64Counter("chn.sub.msg_size", "Total size of channel subscribe msg", "bytes"); + } + // register hook core_ptr_->RegisterHookFunc(runtime::core::AimRTCore::State::kPostInitLog, [this] { SetPluginLogger(); }); @@ -118,7 +174,12 @@ void OpenTelemetryPlugin::Shutdown() noexcept { try { if (!init_flag_) return; - provider_.reset(); + meter_.reset(); + meter_provider_.reset(); + + tracer_.reset(); + trace_provider_.reset(); + propagator_.reset(); } catch (const std::exception& e) { @@ -134,83 +195,120 @@ void OpenTelemetryPlugin::SetPluginLogger() { void OpenTelemetryPlugin::RegisterChannelFilter() { auto& channel_manager = core_ptr_->GetChannelManager(); - channel_manager.SetPassedContextMetaKeys( - {std::string(kCtxKeyStartNewTrace), - std::string(kCtxKeyTraceParent), - std::string(kCtxKeyTraceState)}); + if (enable_trace_) { + channel_manager.AddPassedContextMetaKeys( + {std::string(kCtxKeyStartNewTrace), + std::string(kCtxKeyTraceParent), + std::string(kCtxKeyTraceState)}); - channel_manager.RegisterPublishFilter( - "otp_trace", - [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, - aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { - ChannelFilter(trace_api::SpanKind::kProducer, true, msg_wrapper, std::move(h)); - }); + channel_manager.RegisterPublishFilter( + "otp_trace", + [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { + ChannelTraceFilter(ChannelFilterType::kPublisher, true, msg_wrapper, std::move(h)); + }); - channel_manager.RegisterPublishFilter( - "otp_simple_trace", - [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, - aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { - ChannelFilter(trace_api::SpanKind::kProducer, false, msg_wrapper, std::move(h)); - }); + channel_manager.RegisterPublishFilter( + "otp_simple_trace", + [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { + ChannelTraceFilter(ChannelFilterType::kPublisher, false, msg_wrapper, std::move(h)); + }); - channel_manager.RegisterSubscribeFilter( - "otp_trace", - [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, - aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { - ChannelFilter(trace_api::SpanKind::kConsumer, true, msg_wrapper, std::move(h)); - }); + channel_manager.RegisterSubscribeFilter( + "otp_trace", + [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { + ChannelTraceFilter(ChannelFilterType::kSubscriber, true, msg_wrapper, std::move(h)); + }); - channel_manager.RegisterSubscribeFilter( - "otp_simple_trace", - [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, - aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { - ChannelFilter(trace_api::SpanKind::kConsumer, false, msg_wrapper, std::move(h)); - }); + channel_manager.RegisterSubscribeFilter( + "otp_simple_trace", + [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { + ChannelTraceFilter(ChannelFilterType::kSubscriber, false, msg_wrapper, std::move(h)); + }); + } + + if (enable_metrics_) { + channel_manager.RegisterPublishFilter( + "otp_metrics", + [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { + ChannelMetricsFilter(ChannelFilterType::kPublisher, msg_wrapper, std::move(h)); + }); + + channel_manager.RegisterSubscribeFilter( + "otp_metrics", + [this](aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { + ChannelMetricsFilter(ChannelFilterType::kSubscriber, msg_wrapper, std::move(h)); + }); + } } void OpenTelemetryPlugin::RegisterRpcFilter() { auto& rpc_manager = core_ptr_->GetRpcManager(); - rpc_manager.SetPassedContextMetaKeys( - {std::string(kCtxKeyStartNewTrace), - std::string(kCtxKeyTraceParent), - std::string(kCtxKeyTraceState)}); + if (enable_trace_) { + rpc_manager.AddPassedContextMetaKeys( + {std::string(kCtxKeyStartNewTrace), + std::string(kCtxKeyTraceParent), + std::string(kCtxKeyTraceState)}); - rpc_manager.RegisterClientFilter( - "otp_trace", - [this](const std::shared_ptr& wrapper_ptr, - aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { - RpcFilter(trace_api::SpanKind::kClient, true, wrapper_ptr, std::move(h)); - }); + rpc_manager.RegisterClientFilter( + "otp_trace", + [this](const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { + RpcTraceFilter(RpcFilterType::kClient, true, wrapper_ptr, std::move(h)); + }); - rpc_manager.RegisterClientFilter( - "otp_simple_trace", - [this](const std::shared_ptr& wrapper_ptr, - aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { - RpcFilter(trace_api::SpanKind::kClient, false, wrapper_ptr, std::move(h)); - }); + rpc_manager.RegisterClientFilter( + "otp_simple_trace", + [this](const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { + RpcTraceFilter(RpcFilterType::kClient, false, wrapper_ptr, std::move(h)); + }); - rpc_manager.RegisterServerFilter( - "otp_trace", - [this](const std::shared_ptr& wrapper_ptr, - aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { - RpcFilter(trace_api::SpanKind::kServer, true, wrapper_ptr, std::move(h)); - }); + rpc_manager.RegisterServerFilter( + "otp_trace", + [this](const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { + RpcTraceFilter(RpcFilterType::kServer, true, wrapper_ptr, std::move(h)); + }); - rpc_manager.RegisterServerFilter( - "otp_simple_trace", - [this](const std::shared_ptr& wrapper_ptr, - aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { - RpcFilter(trace_api::SpanKind::kServer, false, wrapper_ptr, std::move(h)); - }); + rpc_manager.RegisterServerFilter( + "otp_simple_trace", + [this](const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { + RpcTraceFilter(RpcFilterType::kServer, false, wrapper_ptr, std::move(h)); + }); + } + + if (enable_metrics_) { + rpc_manager.RegisterClientFilter( + "otp_metrics", + [this](const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { + RpcMetricsFilter(RpcFilterType::kClient, wrapper_ptr, std::move(h)); + }); + + rpc_manager.RegisterServerFilter( + "otp_metrics", + [this](const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { + RpcMetricsFilter(RpcFilterType::kServer, wrapper_ptr, std::move(h)); + }); + } } -void OpenTelemetryPlugin::ChannelFilter( - opentelemetry::trace::SpanKind kind, +void OpenTelemetryPlugin::ChannelTraceFilter( + ChannelFilterType type, bool upload_msg, aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { auto ctx_ref = msg_wrapper.ctx_ref; + const auto& info = msg_wrapper.info; // 如果设置了全局强制trace,或者context强制设置了start_new_trace,或者上层传递了span,则新启动一个span bool start_new_trace = options_.force_trace; @@ -221,21 +319,20 @@ void OpenTelemetryPlugin::ChannelFilter( ctx_ref.SetMetaValue(kCtxKeyStartNewTrace, "true"); } - auto tracer = provider_->GetTracer(options_.node_name); ContextCarrier carrier(ctx_ref); // 解压传进来的context,得到父span - trace_api::StartSpanOptions op{ - .kind = kind, - }; + trace_api::StartSpanOptions op; + op.kind = (type == ChannelFilterType::kPublisher) + ? trace_api::SpanKind::kProducer + : trace_api::SpanKind::kConsumer; opentelemetry::context::Context input_ot_ctx; auto extract_ctx = propagator_->Extract(carrier, input_ot_ctx); auto extract_ctx_val = extract_ctx.GetValue(trace_api::kSpanKey); - if (!::opentelemetry::nostd::holds_alternative<::opentelemetry::nostd::monostate>(extract_ctx_val)) { - auto parent_span = - ::opentelemetry::nostd::get<::opentelemetry::nostd::shared_ptr<::opentelemetry::trace::Span>>(extract_ctx_val); + if (!std::holds_alternative(extract_ctx_val)) { + auto parent_span = std::get>(extract_ctx_val); op.parent = parent_span->GetContext(); start_new_trace = true; } @@ -248,20 +345,24 @@ void OpenTelemetryPlugin::ChannelFilter( // 需要启动一个新trace std::string span_name = msg_wrapper.info.topic_name + "/" + msg_wrapper.info.msg_type; - auto span = tracer->StartSpan(ToNoStdStringView(span_name), op); + auto span = tracer_->StartSpan(span_name, op); + + // 先发布数据 + h(msg_wrapper); // 将当前span的context打包 opentelemetry::context::Context output_ot_ctx(trace_api::kSpanKey, span); propagator_->Inject(carrier, output_ot_ctx); + // 添加base信息 + span->SetAttribute("module_name", info.module_name); + // 添加context中的属性 auto keys = ctx_ref.GetMetaKeys(); - for (auto& itr : keys) { - span->SetAttribute(ToNoStdStringView(itr), ToNoStdStringView(ctx_ref.GetMetaValue(itr))); + for (auto& item : keys) { + span->SetAttribute(item, ctx_ref.GetMetaValue(item)); } - h(msg_wrapper); - if (upload_msg) { // 序列化包成json auto buf_ptr = aimrt::runtime::core::channel::TrySerializeMsgWithCache(msg_wrapper, "json"); @@ -274,8 +375,8 @@ void OpenTelemetryPlugin::ChannelFilter( span->End(); } -void OpenTelemetryPlugin::RpcFilter( - opentelemetry::trace::SpanKind kind, +void OpenTelemetryPlugin::RpcTraceFilter( + RpcFilterType type, bool upload_msg, const std::shared_ptr& wrapper_ptr, aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { @@ -290,21 +391,20 @@ void OpenTelemetryPlugin::RpcFilter( ctx_ref.SetMetaValue(kCtxKeyStartNewTrace, "true"); } - auto tracer = provider_->GetTracer(options_.node_name); ContextCarrier carrier(ctx_ref); // 解压传进来的context,得到父span - trace_api::StartSpanOptions op{ - .kind = kind, - }; + trace_api::StartSpanOptions op; + op.kind = (type == RpcFilterType::kClient) + ? trace_api::SpanKind::kClient + : trace_api::SpanKind::kServer; opentelemetry::context::Context input_ot_ctx; auto extract_ctx = propagator_->Extract(carrier, input_ot_ctx); auto extract_ctx_val = extract_ctx.GetValue(trace_api::kSpanKey); - if (!::opentelemetry::nostd::holds_alternative<::opentelemetry::nostd::monostate>(extract_ctx_val)) { - auto parent_span = - ::opentelemetry::nostd::get<::opentelemetry::nostd::shared_ptr<::opentelemetry::trace::Span>>(extract_ctx_val); + if (!std::holds_alternative(extract_ctx_val)) { + auto parent_span = std::get>(extract_ctx_val); op.parent = parent_span->GetContext(); start_new_trace = true; } @@ -316,18 +416,12 @@ void OpenTelemetryPlugin::RpcFilter( } // 需要启动一个新trace - auto span = tracer->StartSpan(ToNoStdStringView(ctx_ref.GetFunctionName()), op); + auto span = tracer_->StartSpan(ctx_ref.GetFunctionName(), op); // 将当前span的context打包 opentelemetry::context::Context output_ot_ctx(trace_api::kSpanKey, span); propagator_->Inject(carrier, output_ot_ctx); - // 添加context中的属性 - auto keys = ctx_ref.GetMetaKeys(); - for (auto& itr : keys) { - span->SetAttribute(ToNoStdStringView(itr), ToNoStdStringView(ctx_ref.GetMetaValue(itr))); - } - wrapper_ptr->callback = [upload_msg, wrapper_ptr, @@ -339,6 +433,18 @@ void OpenTelemetryPlugin::RpcFilter( span->SetStatus(trace_api::StatusCode::kError, status.ToString()); } + auto ctx_ref = wrapper_ptr->ctx_ref; + const auto& info = wrapper_ptr->info; + + // 添加base信息 + span->SetAttribute("module_name", info.module_name); + + // 添加context中的属性 + auto keys = ctx_ref.GetMetaKeys(); + for (auto& item : keys) { + span->SetAttribute(item, ctx_ref.GetMetaValue(item)); + } + if (upload_msg) { // 序列化req/rsp为json auto req_buf_ptr = aimrt::runtime::core::rpc::TrySerializeReqWithCache(*wrapper_ptr, "json"); @@ -362,4 +468,78 @@ void OpenTelemetryPlugin::RpcFilter( h(wrapper_ptr); } +void OpenTelemetryPlugin::ChannelMetricsFilter( + ChannelFilterType type, + aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h) { + // publish msg first + h(msg_wrapper); + + // get counter + metrics_api::Counter* msg_num_counter_ptr = nullptr; + metrics_api::Counter* msg_size_counter_ptr = nullptr; + + if (type == ChannelFilterType::kPublisher) { + msg_num_counter_ptr = chn_pub_msg_num_counter_.get(); + msg_size_counter_ptr = chn_pub_msg_size_counter_.get(); + } else { + msg_num_counter_ptr = chn_sub_msg_num_counter_.get(); + msg_size_counter_ptr = chn_sub_msg_size_counter_.get(); + } + + // make labels + auto ctx_ref = msg_wrapper.ctx_ref; + const auto& info = msg_wrapper.info; + + std::map labels{ + {"topic_name", info.topic_name}, + {"msg_type", info.msg_type}, + {"module_name", info.module_name}, + }; + + // TODO 这里是否有必要?对性能影响有多大? + auto keys = ctx_ref.GetMetaKeys(); + for (auto& item : keys) { + labels.emplace(item, ctx_ref.GetMetaValue(item)); + } + + // msg num + msg_num_counter_ptr->Add(1, labels); + + // msg size + std::string_view serialization_type; + size_t msg_size = 0; + + const auto& serialization_cache = msg_wrapper.serialization_cache; + + if (serialization_cache.size() == 1) { + serialization_type = serialization_cache.begin()->first; + msg_size = serialization_cache.begin()->second->BufferSize(); + } else { + auto serialization_type_span = info.msg_type_support_ref.SerializationTypesSupportedListSpan(); + + for (auto item : serialization_type_span) { + auto cur_serialization_type = aimrt::util::ToStdStringView(item); + + auto finditr = serialization_cache.find(cur_serialization_type); + if (finditr == serialization_cache.end()) [[unlikely]] + continue; + + serialization_type = cur_serialization_type; + msg_size = finditr->second->BufferSize(); + break; + } + } + + labels.emplace("serialization_type", serialization_type); + msg_size_counter_ptr->Add(msg_size, labels); +} + +void OpenTelemetryPlugin::RpcMetricsFilter( + RpcFilterType type, + const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h) { + h(wrapper_ptr); +} + } // namespace aimrt::plugins::opentelemetry_plugin diff --git a/src/plugins/opentelemetry_plugin/opentelemetry_plugin.h b/src/plugins/opentelemetry_plugin/opentelemetry_plugin.h index 3cf953c8d..efec92388 100644 --- a/src/plugins/opentelemetry_plugin/opentelemetry_plugin.h +++ b/src/plugins/opentelemetry_plugin/opentelemetry_plugin.h @@ -8,9 +8,26 @@ #include "aimrt_core_plugin_interface/aimrt_core_plugin_base.h" -#include +#include "opentelemetry/context/propagation/text_map_propagator.h" +#include "opentelemetry/exporters/otlp/otlp_environment.h" +#include "opentelemetry/exporters/otlp/otlp_http.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h" +#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h" +#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h" +#include "opentelemetry/metrics/meter_provider.h" +#include "opentelemetry/metrics/provider.h" +#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_factory.h" +#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_options.h" +#include "opentelemetry/sdk/metrics/meter_context.h" +#include "opentelemetry/sdk/metrics/meter_context_factory.h" +#include "opentelemetry/sdk/metrics/meter_provider.h" +#include "opentelemetry/sdk/metrics/meter_provider_factory.h" +#include "opentelemetry/sdk/metrics/metric_reader.h" +#include "opentelemetry/sdk/metrics/push_metric_exporter.h" +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" +#include "opentelemetry/sdk/metrics/view/view_registry.h" +#include "opentelemetry/sdk/metrics/view/view_registry_factory.h" #include "opentelemetry/sdk/trace/batch_span_processor_factory.h" #include "opentelemetry/sdk/trace/batch_span_processor_options.h" #include "opentelemetry/sdk/trace/exporter.h" @@ -20,10 +37,12 @@ #include "opentelemetry/sdk/trace/tracer_provider.h" #include "opentelemetry/sdk/trace/tracer_provider_factory.h" #include "opentelemetry/sdk/version/version.h" +#include "opentelemetry/trace/propagation/http_trace_context.h" #include "opentelemetry/trace/provider.h" #include "opentelemetry/trace/scope.h" #include "opentelemetry/trace/span.h" #include "opentelemetry/trace/span_context.h" +#include "opentelemetry/trace/span_metadata.h" #include "opentelemetry/trace/tracer.h" #include "opentelemetry/trace/tracer_provider.h" @@ -36,9 +55,14 @@ class OpenTelemetryPlugin : public AimRTCorePluginBase { public: struct Options { std::string node_name; + std::string trace_otlp_http_exporter_url; bool force_trace = false; + std::string metrics_otlp_http_exporter_url; + uint32_t metrics_export_interval_ms = 15000; + uint32_t metrics_export_timeout_ms = 5000; + struct Attribute { std::string key; std::string val; @@ -60,18 +84,38 @@ class OpenTelemetryPlugin : public AimRTCorePluginBase { void RegisterChannelFilter(); void RegisterRpcFilter(); - void ChannelFilter( - opentelemetry::trace::SpanKind kind, + enum class ChannelFilterType { + kPublisher, + kSubscriber + }; + + enum class RpcFilterType { + kClient, + kServer + }; + + void ChannelTraceFilter( + ChannelFilterType type, bool upload_msg, aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h); - void RpcFilter( - opentelemetry::trace::SpanKind kind, + void RpcTraceFilter( + RpcFilterType type, bool upload_msg, const std::shared_ptr& wrapper_ptr, aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h); + void ChannelMetricsFilter( + ChannelFilterType type, + aimrt::runtime::core::channel::MsgWrapper& msg_wrapper, + aimrt::runtime::core::channel::FrameworkAsyncChannelHandle&& h); + + void RpcMetricsFilter( + RpcFilterType type, + const std::shared_ptr& wrapper_ptr, + aimrt::runtime::core::rpc::FrameworkAsyncRpcHandle&& h); + private: runtime::core::AimRTCore* core_ptr_ = nullptr; @@ -79,8 +123,31 @@ class OpenTelemetryPlugin : public AimRTCorePluginBase { bool init_flag_ = false; - std::shared_ptr provider_; std::shared_ptr propagator_; + + // trace + bool enable_trace_ = false; + std::shared_ptr trace_provider_; + std::shared_ptr tracer_; + + // metrics + bool enable_metrics_ = false; + std::shared_ptr meter_provider_; + std::shared_ptr meter_; + + using u64_counter = std::unique_ptr>; + + u64_counter chn_pub_msg_num_counter_; + u64_counter chn_sub_msg_num_counter_; + u64_counter chn_pub_msg_size_counter_; + u64_counter chn_sub_msg_size_counter_; + + u64_counter rpc_client_invoke_num_counter_; + u64_counter rpc_server_invoke_num_counter_; + u64_counter rpc_client_req_size_counter_; + u64_counter rpc_client_rsp_size_counter_; + u64_counter rpc_server_req_size_counter_; + u64_counter rpc_server_rsp_size_counter_; }; } // namespace aimrt::plugins::opentelemetry_plugin diff --git a/src/plugins/opentelemetry_plugin/util.h b/src/plugins/opentelemetry_plugin/util.h index 86d613145..85fb56fb7 100644 --- a/src/plugins/opentelemetry_plugin/util.h +++ b/src/plugins/opentelemetry_plugin/util.h @@ -5,8 +5,6 @@ #include -#include "opentelemetry/nostd/string_view.h" - namespace aimrt::plugins::opentelemetry_plugin { static constexpr std::string_view kCtxKeyPrefix = "aimrt_otp-"; @@ -15,12 +13,4 @@ static constexpr std::string_view kCtxKeyStartNewTrace = "aimrt_otp-start_new_tr static constexpr std::string_view kCtxKeyTraceParent = "aimrt_otp-traceparent"; static constexpr std::string_view kCtxKeyTraceState = "aimrt_otp-tracestate"; -inline opentelemetry::nostd::string_view ToNoStdStringView(std::string_view s) { - return opentelemetry::nostd::string_view(s.data(), s.size()); -} - -inline std::string_view ToStdStringView(opentelemetry::nostd::string_view s) { - return std::string_view(s.data(), s.size()); -} - } // namespace aimrt::plugins::opentelemetry_plugin \ No newline at end of file diff --git a/src/plugins/record_playback_plugin/record_action.cc b/src/plugins/record_playback_plugin/record_action.cc index a4d8ab18e..19508345e 100644 --- a/src/plugins/record_playback_plugin/record_action.cc +++ b/src/plugins/record_playback_plugin/record_action.cc @@ -225,6 +225,11 @@ void RecordAction::RegisterGetTypeSupportFunc( get_type_support_func_ = get_type_support_func; } +size_t RecordAction::GetDbFileSize() const { + if (cur_db_file_path_.empty() || !std::filesystem::exists(cur_db_file_path_)) return 0; + return std::filesystem::file_size(cur_db_file_path_); +} + void RecordAction::AddRecord(OneRecord&& record) { if (state_.load() != State::kStart) [[unlikely]] { return; @@ -365,9 +370,10 @@ void RecordAction::AddRecordImpl(OneRecord&& record) { if (db_ == nullptr) [[unlikely]] { // first record OpenNewDb(record.timestamp); - } else if (cur_data_size_ > max_bag_size_) [[unlikely]] { - // check db size + } else if (cur_data_size_ * estimated_overhead_ >= max_bag_size_) [[unlikely]] { + size_t original_cur_data_size = cur_data_size_; cur_data_size_ = 0; + estimated_overhead_ = std::max(1.0, static_cast(GetDbFileSize()) / original_cur_data_size); OpenNewDb(record.timestamp); } @@ -418,17 +424,17 @@ void RecordAction::OpenNewDb(uint64_t start_timestamp) { std::string cur_db_file_name = bag_base_name_ + "_" + std::to_string(cur_db_file_index_) + ".db3"; - auto db_file_path = (real_bag_path_ / cur_db_file_name).string(); + cur_db_file_path_ = (real_bag_path_ / cur_db_file_name).string(); ++cur_db_file_index_; // open db - int ret = sqlite3_open(db_file_path.c_str(), &db_); + int ret = sqlite3_open(cur_db_file_path_.c_str(), &db_); AIMRT_CHECK_ERROR_THROW(ret == SQLITE_OK, "Sqlite3 open db file failed, path: {}, ret: {}, error info: {}", - db_file_path, ret, sqlite3_errmsg(db_)); + cur_db_file_path_, ret, sqlite3_errmsg(db_)); - AIMRT_TRACE("Open new db, path: {}", db_file_path); + AIMRT_TRACE("Open new db, path: {}", cur_db_file_path_); // sqlite3_exec(db_, "PRAGMA synchronous = OFF; ", 0, 0, 0); diff --git a/src/plugins/record_playback_plugin/record_action.h b/src/plugins/record_playback_plugin/record_action.h index 36d5f1ffe..2e8811253 100644 --- a/src/plugins/record_playback_plugin/record_action.h +++ b/src/plugins/record_playback_plugin/record_action.h @@ -81,6 +81,7 @@ class RecordAction { void OpenNewDb(uint64_t start_timestamp); void CloseDb(); + size_t GetDbFileSize() const; enum class State : uint32_t { kPreInit, @@ -101,12 +102,14 @@ class RecordAction { size_t max_bag_size_ = 0; size_t cur_data_size_ = 0; + double estimated_overhead_ = 1.5; size_t cur_exec_count_ = 0; std::deque> buf_array_view_cache_; std::deque> buf_cache_; std::filesystem::path real_bag_path_; + std::string cur_db_file_path_; std::string bag_base_name_; uint32_t cur_db_file_index_ = 0; diff --git a/src/plugins/ros2_plugin/ros2_channel_backend.cc b/src/plugins/ros2_plugin/ros2_channel_backend.cc index 4bb8bcd29..1e88376ba 100644 --- a/src/plugins/ros2_plugin/ros2_channel_backend.cc +++ b/src/plugins/ros2_plugin/ros2_channel_backend.cc @@ -221,7 +221,7 @@ bool Ros2ChannelBackend::RegisterPublishType( return false; } - AIMRT_INFO("ros backend register publish type for topic '{}' success.", info.topic_name); + AIMRT_INFO("ros2 backend register publish type for topic '{}' success.", info.topic_name); return true; } @@ -236,7 +236,7 @@ bool Ros2ChannelBackend::RegisterPublishType( ros2_node_ptr_->create_publisher(real_ros2_topic_name, qos)); } - AIMRT_INFO("ros backend register publish type for topic '{}' success, real ros2 topic name is '{}'.", + AIMRT_INFO("ros2 backend register publish type for topic '{}' success, real ros2 topic name is '{}'.", info.topic_name, real_ros2_topic_name); return true; diff --git a/src/plugins/ros2_plugin/ros2_plugin.cc b/src/plugins/ros2_plugin/ros2_plugin.cc index 2b8484f3c..d9909f231 100644 --- a/src/plugins/ros2_plugin/ros2_plugin.cc +++ b/src/plugins/ros2_plugin/ros2_plugin.cc @@ -56,7 +56,10 @@ bool Ros2Plugin::Initialize(runtime::core::AimRTCore* core_ptr) noexcept { rclcpp::InitOptions op; op.shutdown_on_signal = false; - rclcpp::init(0, nullptr, op); + + if (!rclcpp::ok()) { + rclcpp::init(0, nullptr, op); + } ros2_node_ptr_ = std::make_shared(options_.node_name); diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index 1888e1372..142f8205d 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -3,7 +3,6 @@ set_namespace() -add_subdirectory(common) add_subdirectory(core) add_subdirectory(main) diff --git a/src/runtime/common/CMakeLists.txt b/src/runtime/common/CMakeLists.txt deleted file mode 100644 index c29a324fe..000000000 --- a/src/runtime/common/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023, AgiBot Inc. -# All rights reserved. - -set_namespace() - -add_subdirectory(net) diff --git a/src/runtime/core/CMakeLists.txt b/src/runtime/core/CMakeLists.txt index 28fed6d43..8a7c87f27 100644 --- a/src/runtime/core/CMakeLists.txt +++ b/src/runtime/core/CMakeLists.txt @@ -35,7 +35,7 @@ target_include_directories( target_link_libraries( ${CUR_TARGET_NAME} PUBLIC ${CMAKE_DL_LIBS} - Boost::asio + asio::asio yaml-cpp::yaml-cpp TBB::tbb aimrt::interface::aimrt_module_cpp_interface diff --git a/src/runtime/core/channel/channel_manager.cc b/src/runtime/core/channel/channel_manager.cc index 550f67d01..58f8e9704 100644 --- a/src/runtime/core/channel/channel_manager.cc +++ b/src/runtime/core/channel/channel_manager.cc @@ -356,7 +356,7 @@ void ChannelManager::RegisterSubscribeFilter(std::string_view name, FrameworkAsy subscribe_filter_manager_.RegisterFilter(name, std::move(filter)); } -void ChannelManager::SetPassedContextMetaKeys(const std::unordered_set& keys) { +void ChannelManager::AddPassedContextMetaKeys(const std::unordered_set& keys) { AIMRT_CHECK_ERROR_THROW( state_.load() == State::kPreInit, "Method can only be called when state is 'PreInit'."); diff --git a/src/runtime/core/channel/channel_manager.h b/src/runtime/core/channel/channel_manager.h index f83c395cf..9a588c5d7 100644 --- a/src/runtime/core/channel/channel_manager.h +++ b/src/runtime/core/channel/channel_manager.h @@ -80,7 +80,7 @@ class ChannelManager { void RegisterPublishFilter(std::string_view name, FrameworkAsyncChannelFilter&& filter); void RegisterSubscribeFilter(std::string_view name, FrameworkAsyncChannelFilter&& filter); - void SetPassedContextMetaKeys(const std::unordered_set& keys); + void AddPassedContextMetaKeys(const std::unordered_set& keys); bool Subscribe(SubscribeWrapper&& wrapper) { return channel_backend_manager_.Subscribe(std::move(wrapper)); diff --git a/src/runtime/core/executor/asio_strand_executor.cc b/src/runtime/core/executor/asio_strand_executor.cc index 5d5fbbd3b..7b5fff1ec 100644 --- a/src/runtime/core/executor/asio_strand_executor.cc +++ b/src/runtime/core/executor/asio_strand_executor.cc @@ -61,7 +61,7 @@ void AsioStrandExecutor::Initialize(std::string_view name, io_ptr, "Invalide bind asio thread executor name, can not get asio io context."); - strand_ptr_ = std::make_unique(boost::asio::make_strand(*io_ptr)); + strand_ptr_ = std::make_unique(asio::make_strand(*io_ptr)); options_node = options_; } @@ -79,7 +79,7 @@ void AsioStrandExecutor::Shutdown() { void AsioStrandExecutor::Execute(aimrt::executor::Task&& task) noexcept { try { - boost::asio::post(*strand_ptr_, std::move(task)); + asio::post(*strand_ptr_, std::move(task)); } catch (const std::exception& e) { AIMRT_ERROR("{}", e.what()); } @@ -88,10 +88,10 @@ void AsioStrandExecutor::Execute(aimrt::executor::Task&& task) noexcept { void AsioStrandExecutor::ExecuteAt( std::chrono::system_clock::time_point tp, aimrt::executor::Task&& task) noexcept { try { - auto timer_ptr = std::make_shared(*strand_ptr_); + auto timer_ptr = std::make_shared(*strand_ptr_); timer_ptr->expires_at(tp); timer_ptr->async_wait([this, timer_ptr, - task{std::move(task)}](boost::system::error_code ec) { + task{std::move(task)}](asio::error_code ec) { if (ec) [[unlikely]] { AIMRT_ERROR("Asio strand executor '{}' timer get err, code '{}', msg: {}", Name(), ec.value(), ec.message()); diff --git a/src/runtime/core/executor/asio_strand_executor.h b/src/runtime/core/executor/asio_strand_executor.h index c78ad901e..20937307a 100644 --- a/src/runtime/core/executor/asio_strand_executor.h +++ b/src/runtime/core/executor/asio_strand_executor.h @@ -8,7 +8,7 @@ #include "yaml-cpp/yaml.h" -#include +#include "asio.hpp" namespace aimrt::runtime::core::executor { @@ -26,7 +26,7 @@ class AsioStrandExecutor : public ExecutorBase { kShutdown, }; - using GetAsioHandle = std::function; + using GetAsioHandle = std::function; public: AsioStrandExecutor() @@ -66,7 +66,7 @@ class AsioStrandExecutor : public ExecutorBase { GetAsioHandle get_asio_handle_; - using Strand = boost::asio::strand; + using Strand = asio::strand; std::unique_ptr strand_ptr_; }; diff --git a/src/runtime/core/executor/asio_thread_executor.cc b/src/runtime/core/executor/asio_thread_executor.cc index bb7a1a5aa..806fbc450 100644 --- a/src/runtime/core/executor/asio_thread_executor.cc +++ b/src/runtime/core/executor/asio_thread_executor.cc @@ -63,9 +63,9 @@ void AsioThreadExecutor::Initialize(std::string_view name, options_.thread_num > 0, "Invalide asio thread executor options, thread num is zero."); - io_ptr_ = std::make_unique(options_.thread_num); + io_ptr_ = std::make_unique(options_.thread_num); work_guard_ptr_ = std::make_unique< - boost::asio::executor_work_guard>( + asio::executor_work_guard>( io_ptr_->get_executor()); thread_id_vec_.resize(options_.thread_num); @@ -156,7 +156,7 @@ void AsioThreadExecutor::Execute(aimrt::executor::Task&& task) noexcept { } try { - boost::asio::post(*io_ptr_, std::move(task)); + asio::post(*io_ptr_, std::move(task)); } catch (const std::exception& e) { fprintf(stderr, "Asio thread executor '%s' execute Task get exception: %s\n", name_.c_str(), e.what()); } @@ -188,10 +188,10 @@ void AsioThreadExecutor::ExecuteAt( } try { - auto timer_ptr = std::make_shared(*io_ptr_); + auto timer_ptr = std::make_shared(*io_ptr_); timer_ptr->expires_at(tp); timer_ptr->async_wait([this, timer_ptr, - task{std::move(task)}](boost::system::error_code ec) { + task{std::move(task)}](asio::error_code ec) { if (ec) [[unlikely]] { AIMRT_ERROR("Asio thread executor '{}' timer get err, code '{}', msg: {}", Name(), ec.value(), ec.message()); diff --git a/src/runtime/core/executor/asio_thread_executor.h b/src/runtime/core/executor/asio_thread_executor.h index e8ba8aae0..a3466311b 100644 --- a/src/runtime/core/executor/asio_thread_executor.h +++ b/src/runtime/core/executor/asio_thread_executor.h @@ -15,7 +15,7 @@ #include "yaml-cpp/yaml.h" -#include +#include "asio.hpp" namespace aimrt::runtime::core::executor { @@ -66,7 +66,7 @@ class AsioThreadExecutor : public ExecutorBase { void SetLogger(const std::shared_ptr& logger_ptr) { logger_ptr_ = logger_ptr; } const aimrt::common::util::LoggerWrapper& GetLogger() const { return *logger_ptr_; } - boost::asio::io_context* IOCTX() { return io_ptr_.get(); } + asio::io_context* IOCTX() { return io_ptr_.get(); } private: std::string name_; @@ -78,9 +78,9 @@ class AsioThreadExecutor : public ExecutorBase { uint32_t queue_warn_threshold_; std::atomic_uint32_t queue_task_num_ = 0; - std::unique_ptr io_ptr_; + std::unique_ptr io_ptr_; std::unique_ptr< - boost::asio::executor_work_guard> + asio::executor_work_guard> work_guard_ptr_; std::vector thread_id_vec_; diff --git a/src/runtime/core/executor/executor_manager.cc b/src/runtime/core/executor/executor_manager.cc index 00933bbec..ba13b5246 100644 --- a/src/runtime/core/executor/executor_manager.cc +++ b/src/runtime/core/executor/executor_manager.cc @@ -177,7 +177,7 @@ void ExecutorManager::RegisterAsioExecutorGenFunc() { auto ptr = std::make_unique(); ptr->SetLogger(logger_ptr_); ptr->RegisterGetAsioHandle( - [this](std::string_view name) -> boost::asio::io_context* { + [this](std::string_view name) -> asio::io_context* { auto itr = std::find_if( executor_vec_.begin(), executor_vec_.end(), diff --git a/src/runtime/core/executor/guard_thread_executor_test.cc b/src/runtime/core/executor/guard_thread_executor_test.cc index 2bd73c055..8e7071ead 100644 --- a/src/runtime/core/executor/guard_thread_executor_test.cc +++ b/src/runtime/core/executor/guard_thread_executor_test.cc @@ -23,7 +23,7 @@ thread_bind_cpu: [0] [&is_executed]() mutable { is_executed = true; }); guard_thread_executor.Execute(std::ref(task)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_TRUE(is_executed); guard_thread_executor.Shutdown(); diff --git a/src/runtime/core/executor/simple_thread_executor_test.cc b/src/runtime/core/executor/simple_thread_executor_test.cc index 49bc32d9a..f8bdad015 100644 --- a/src/runtime/core/executor/simple_thread_executor_test.cc +++ b/src/runtime/core/executor/simple_thread_executor_test.cc @@ -24,7 +24,7 @@ thread_bind_cpu: [0] [&is_executed]() mutable { is_executed = true; }); simple_thread_executor.Execute(std::ref(task)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_TRUE(is_executed); simple_thread_executor.Shutdown(); diff --git a/src/runtime/core/rpc/rpc_manager.cc b/src/runtime/core/rpc/rpc_manager.cc index 2ca9bf68a..4206d1934 100644 --- a/src/runtime/core/rpc/rpc_manager.cc +++ b/src/runtime/core/rpc/rpc_manager.cc @@ -347,7 +347,7 @@ void RpcManager::RegisterServerFilter(std::string_view name, FrameworkAsyncRpcFi server_filter_manager_.RegisterFilter(name, std::move(filter)); } -void RpcManager::SetPassedContextMetaKeys(const std::unordered_set& keys) { +void RpcManager::AddPassedContextMetaKeys(const std::unordered_set& keys) { AIMRT_CHECK_ERROR_THROW( state_.load() == State::kPreInit, "Method can only be called when state is 'PreInit'."); diff --git a/src/runtime/core/rpc/rpc_manager.h b/src/runtime/core/rpc/rpc_manager.h index 679a75242..455b73719 100644 --- a/src/runtime/core/rpc/rpc_manager.h +++ b/src/runtime/core/rpc/rpc_manager.h @@ -83,7 +83,7 @@ class RpcManager { void RegisterClientFilter(std::string_view name, FrameworkAsyncRpcFilter&& filter); void RegisterServerFilter(std::string_view name, FrameworkAsyncRpcFilter&& filter); - void SetPassedContextMetaKeys(const std::unordered_set& keys); + void AddPassedContextMetaKeys(const std::unordered_set& keys); const RpcRegistry* GetRpcRegistry() const; const std::vector& GetUsedRpcBackend() const; diff --git a/src/runtime/main/CMakeLists.txt b/src/runtime/main/CMakeLists.txt index 5fc01307a..c67618756 100644 --- a/src/runtime/main/CMakeLists.txt +++ b/src/runtime/main/CMakeLists.txt @@ -33,6 +33,10 @@ target_link_libraries( PRIVATE gflags::gflags aimrt::runtime::core) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set_target_properties(${CUR_TARGET_NAME} PROPERTIES LINK_FLAGS "-s") +endif() + # Add -Werror option include(AddWerror) add_werror(${CUR_TARGET_NAME}) diff --git a/src/runtime/main/main.cc b/src/runtime/main/main.cc index d5832c617..6a91e5dea 100644 --- a/src/runtime/main/main.cc +++ b/src/runtime/main/main.cc @@ -87,8 +87,7 @@ int32_t main(int32_t argc, char** argv) { signal(SIGTERM, SignalHandler); } - std::cout << "AimRT start." << std::endl; - PrintVersion(); + std::cout << "AimRT start, version: " << util::GetAimRTVersion() << std::endl; try { AimRTCore core; diff --git a/src/runtime/python_runtime/export_channel.h b/src/runtime/python_runtime/export_channel.h index ca63f38db..465ecae2b 100644 --- a/src/runtime/python_runtime/export_channel.h +++ b/src/runtime/python_runtime/export_channel.h @@ -32,7 +32,7 @@ inline void PyPublish( } inline void ExportPublisherRef(pybind11::object m) { - using namespace aimrt::channel; + using aimrt::channel::PublisherRef; pybind11::class_(std::move(m), "PublisherRef") .def(pybind11::init<>()) @@ -41,7 +41,10 @@ inline void ExportPublisherRef(pybind11::object m) { .def("Publish", &PyPublish); } -inline pybind11::bytes channel_empty_py_bytes; +inline const pybind11::bytes& GetChannelEmptyPyBytes() { + static const pybind11::bytes kChannelEmptyPyBytes = pybind11::bytes(""); + return kChannelEmptyPyBytes; +} inline bool PySubscribe( aimrt::channel::SubscriberRef& subscriber_ref, @@ -62,7 +65,7 @@ inline bool PySubscribe( auto ctx_ref = aimrt::channel::ContextRef(ctx_ptr); if (msg_buf.empty()) [[unlikely]] { - callback(ctx_ref.GetSerializationType(), channel_empty_py_bytes); + callback(ctx_ref.GetSerializationType(), GetChannelEmptyPyBytes()); } else { auto msg_buf_bytes = pybind11::bytes(msg_buf); @@ -78,7 +81,7 @@ inline bool PySubscribe( } inline void ExportSubscriberRef(pybind11::object m) { - using namespace aimrt::channel; + using aimrt::channel::SubscriberRef; pybind11::class_(std::move(m), "SubscriberRef") .def(pybind11::init<>()) @@ -87,7 +90,7 @@ inline void ExportSubscriberRef(pybind11::object m) { } inline void ExportChannelHandleRef(pybind11::object m) { - using namespace aimrt::channel; + using aimrt::channel::ChannelHandleRef; pybind11::class_(std::move(m), "ChannelHandleRef") .def(pybind11::init<>()) diff --git a/src/runtime/python_runtime/export_configurator.h b/src/runtime/python_runtime/export_configurator.h index 541cce2c0..f3e4a590c 100644 --- a/src/runtime/python_runtime/export_configurator.h +++ b/src/runtime/python_runtime/export_configurator.h @@ -12,7 +12,7 @@ namespace aimrt::runtime::python_runtime { inline void ExportConfiguratorRef(pybind11::object m) { - using namespace aimrt::configurator; + using aimrt::configurator::ConfiguratorRef; pybind11::class_(std::move(m), "ConfiguratorRef") .def(pybind11::init<>()) diff --git a/src/runtime/python_runtime/export_core.h b/src/runtime/python_runtime/export_core.h index b225fe798..87b6e73b7 100644 --- a/src/runtime/python_runtime/export_core.h +++ b/src/runtime/python_runtime/export_core.h @@ -12,8 +12,6 @@ namespace aimrt::runtime::python_runtime { inline void ExportModuleInfo(pybind11::object m) { - using namespace aimrt; - pybind11::class_(std::move(m), "ModuleInfo") .def(pybind11::init<>()) .def_readwrite("name", &ModuleInfo::name) @@ -26,8 +24,6 @@ inline void ExportModuleInfo(pybind11::object m) { } inline void ExportCoreRef(pybind11::object m) { - using namespace aimrt; - pybind11::class_(std::move(m), "CoreRef") .def(pybind11::init<>()) .def("__bool__", &CoreRef::operator bool) @@ -36,7 +32,8 @@ inline void ExportCoreRef(pybind11::object m) { .def("GetLogger", &CoreRef::GetLogger) .def("GetExecutorManager", &CoreRef::GetExecutorManager) .def("GetRpcHandle", &CoreRef::GetRpcHandle) - .def("GetChannelHandle", &CoreRef::GetChannelHandle); + .def("GetChannelHandle", &CoreRef::GetChannelHandle) + .def("GetParameterHandle", &CoreRef::GetParameterHandle); } } // namespace aimrt::runtime::python_runtime \ No newline at end of file diff --git a/src/runtime/python_runtime/export_core_runtime.h b/src/runtime/python_runtime/export_core_runtime.h index a7295b24f..38245af57 100644 --- a/src/runtime/python_runtime/export_core_runtime.h +++ b/src/runtime/python_runtime/export_core_runtime.h @@ -13,7 +13,7 @@ namespace aimrt::runtime::python_runtime { inline void ExportCoreOptions(pybind11::object m) { - using namespace aimrt::runtime::core; + using aimrt::runtime::core::AimRTCore; pybind11::class_(std::move(m), "CoreOptions") .def(pybind11::init<>()) @@ -21,7 +21,7 @@ inline void ExportCoreOptions(pybind11::object m) { } inline void PyCoreStart(aimrt::runtime::core::AimRTCore& core) { - // 阻塞之前需要释放gil锁 + // Release GIL before blocking pybind11::gil_scoped_release release; core.Start(); pybind11::gil_scoped_acquire acquire; @@ -39,7 +39,7 @@ inline aimrt::CoreRef PyCoreCreateModule( } inline void ExportCore(pybind11::object m) { - using namespace aimrt::runtime::core; + using aimrt::runtime::core::AimRTCore; pybind11::class_(std::move(m), "Core") .def(pybind11::init<>()) diff --git a/src/runtime/python_runtime/export_executor.h b/src/runtime/python_runtime/export_executor.h index 70ac77576..bf5ec8aef 100644 --- a/src/runtime/python_runtime/export_executor.h +++ b/src/runtime/python_runtime/export_executor.h @@ -15,7 +15,7 @@ namespace aimrt::runtime::python_runtime { inline void ExportExecutorManagerRef(pybind11::object m) { - using namespace aimrt::executor; + using aimrt::executor::ExecutorManagerRef; pybind11::class_(std::move(m), "ExecutorManagerRef") .def(pybind11::init<>()) @@ -43,7 +43,7 @@ inline void PyExecutorRefExecuteAfterWrapper( } inline void ExportExecutorRef(pybind11::object m) { - using namespace aimrt::executor; + using aimrt::executor::ExecutorRef; pybind11::class_(std::move(m), "ExecutorRef") .def(pybind11::init<>()) diff --git a/src/runtime/python_runtime/export_logger.h b/src/runtime/python_runtime/export_logger.h index 80dd15322..a86ae2b2c 100644 --- a/src/runtime/python_runtime/export_logger.h +++ b/src/runtime/python_runtime/export_logger.h @@ -12,7 +12,7 @@ namespace aimrt::runtime::python_runtime { inline void ExportLoggerRef(pybind11::object m) { - using namespace aimrt::logger; + using aimrt::logger::LoggerRef; pybind11::class_(std::move(m), "LoggerRef") .def(pybind11::init<>()) diff --git a/src/runtime/python_runtime/export_module_base.h b/src/runtime/python_runtime/export_module_base.h index 4165f5a88..edeefbd0b 100644 --- a/src/runtime/python_runtime/export_module_base.h +++ b/src/runtime/python_runtime/export_module_base.h @@ -33,8 +33,6 @@ class PyModuleBaseAdapter : public ModuleBase { }; inline void ExportModuleBase(pybind11::object m) { - using namespace aimrt; - pybind11::class_>(std::move(m), "ModuleBase") .def(pybind11::init<>()) .def("Info", &ModuleBase::Info) diff --git a/src/runtime/python_runtime/export_parameter.h b/src/runtime/python_runtime/export_parameter.h new file mode 100644 index 000000000..74a67eb2e --- /dev/null +++ b/src/runtime/python_runtime/export_parameter.h @@ -0,0 +1,22 @@ +// Copyright (c) 2023, AgiBot Inc. +// All rights reserved. + +#pragma once + +#include "aimrt_module_cpp_interface/parameter/parameter_handle.h" + +#include "pybind11/pybind11.h" + +namespace aimrt::runtime::python_runtime { + +inline void ExportParameter(pybind11::object m) { + using aimrt::parameter::ParameterHandleRef; + + pybind11::class_(std::move(m), "ParameterHandleRef") + .def(pybind11::init<>()) + .def("__bool__", &ParameterHandleRef::operator bool) + .def("GetParameter", &ParameterHandleRef::GetParameter) + .def("SetParameter", &ParameterHandleRef::SetParameter); +} + +} // namespace aimrt::runtime::python_runtime \ No newline at end of file diff --git a/src/runtime/python_runtime/export_rpc.h b/src/runtime/python_runtime/export_rpc.h index be7445f5b..410184865 100644 --- a/src/runtime/python_runtime/export_rpc.h +++ b/src/runtime/python_runtime/export_rpc.h @@ -14,7 +14,7 @@ namespace aimrt::runtime::python_runtime { inline void ExportRpcStatus(const pybind11::object& m) { - using namespace aimrt::rpc; + using aimrt::rpc::Status; pybind11::enum_(m, "RpcStatusRetCode") .value("OK", AIMRT_RPC_STATUS_OK) @@ -54,7 +54,8 @@ inline void ExportRpcStatus(const pybind11::object& m) { } inline void ExportRpcContext(const pybind11::object& m) { - using namespace aimrt::rpc; + using aimrt::rpc::Context; + using aimrt::rpc::ContextRef; pybind11::class_(m, "RpcContext") .def(pybind11::init<>()) @@ -89,7 +90,10 @@ inline void ExportRpcContext(const pybind11::object& m) { .def("ToString", &ContextRef::ToString); } -inline pybind11::bytes rpc_empty_py_bytes; +inline const pybind11::bytes& GetRpcEmptyPyBytes() { + static const pybind11::bytes kRpcEmptyPyBytes = pybind11::bytes(""); + return kRpcEmptyPyBytes; +} inline void PyRpcServiceBaseRegisterServiceFunc( aimrt::rpc::ServiceBase& service, @@ -114,7 +118,7 @@ inline void PyRpcServiceBaseRegisterServiceFunc( // TODO,未知原因,在此处使用空字符串构造pybind11::bytes时会挂掉。但是在外面构造没有问题 if (req_buf.empty()) [[unlikely]] { - auto [status, rsp_buf_tmp] = service_func(ctx_ref, rpc_empty_py_bytes); + auto [status, rsp_buf_tmp] = service_func(ctx_ref, GetRpcEmptyPyBytes()); rsp_buf = std::move(rsp_buf_tmp); @@ -150,7 +154,7 @@ inline void PyRpcServiceBaseRegisterServiceFunc( } inline void ExportRpcServiceBase(pybind11::object m) { - using namespace aimrt::rpc; + using aimrt::rpc::ServiceBase; pybind11::class_(std::move(m), "ServiceBase") .def(pybind11::init()) @@ -204,7 +208,7 @@ inline std::tuple PyRpcHandleRefInvoke( } inline void ExportRpcHandleRef(pybind11::object m) { - using namespace aimrt::rpc; + using aimrt::rpc::RpcHandleRef; pybind11::class_(std::move(m), "RpcHandleRef") .def(pybind11::init<>()) diff --git a/src/runtime/python_runtime/python_runtime_main.cc b/src/runtime/python_runtime/python_runtime_main.cc index 6015f056a..88a12f60e 100644 --- a/src/runtime/python_runtime/python_runtime_main.cc +++ b/src/runtime/python_runtime/python_runtime_main.cc @@ -8,6 +8,7 @@ #include "python_runtime/export_executor.h" #include "python_runtime/export_logger.h" #include "python_runtime/export_module_base.h" +#include "python_runtime/export_parameter.h" #include "python_runtime/export_rpc.h" #include "python_runtime/export_type_support.h" @@ -52,4 +53,7 @@ PYBIND11_MODULE(aimrt_python_runtime, m) { ExportRpcContext(m); ExportRpcServiceBase(m); ExportRpcHandleRef(m); + + // parameter + ExportParameter(m); } diff --git a/src/tools/protoc_plugin_cpp_gen_aimrt_cpp_rpc/main.cc b/src/tools/protoc_plugin_cpp_gen_aimrt_cpp_rpc/main.cc index 39dee51a2..2b9b3b3f9 100644 --- a/src/tools/protoc_plugin_cpp_gen_aimrt_cpp_rpc/main.cc +++ b/src/tools/protoc_plugin_cpp_gen_aimrt_cpp_rpc/main.cc @@ -128,6 +128,7 @@ bool Register{{service_name}}ClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) class {{service_name}}SyncProxy : public aimrt::rpc::ProxyBase { public: explicit {{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}SyncProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -156,6 +157,7 @@ class {{service_name}}SyncProxy : public aimrt::rpc::ProxyBase { class {{service_name}}AsyncProxy : public aimrt::rpc::ProxyBase { public: explicit {{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}AsyncProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -187,6 +189,7 @@ class {{service_name}}AsyncProxy : public aimrt::rpc::ProxyBase { class {{service_name}}FutureProxy : public aimrt::rpc::ProxyBase { public: explicit {{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}FutureProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -215,6 +218,7 @@ class {{service_name}}FutureProxy : public aimrt::rpc::ProxyBase { class {{service_name}}CoProxy : public aimrt::rpc::CoProxyBase { public: explicit {{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}CoProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -381,6 +385,10 @@ bool Register{{service_name}}ClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) {{for service begin}} {{service_name}}SyncProxy::{{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}SyncProxy::{{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} aimrt::rpc::Status {{service_name}}SyncProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, @@ -421,6 +429,10 @@ aimrt::rpc::Status {{service_name}}SyncProxy::{{rpc_func_name}}( {{for service begin}} {{service_name}}AsyncProxy::{{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}AsyncProxy::{{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} void {{service_name}}AsyncProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, @@ -458,6 +470,10 @@ void {{service_name}}AsyncProxy::{{rpc_func_name}}( {{for service begin}} {{service_name}}FutureProxy::{{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}FutureProxy::{{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} std::future {{service_name}}FutureProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, @@ -499,6 +515,10 @@ std::future {{service_name}}FutureProxy::{{rpc_func_name}}( {{for service begin}} {{service_name}}CoProxy::{{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::CoProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}CoProxy::{{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::CoProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} aimrt::co::Task {{service_name}}CoProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, diff --git a/src/tools/protoc_plugin_py_gen_aimrt_cpp_rpc/protoc_plugin_py_gen_aimrt_cpp_rpc.py b/src/tools/protoc_plugin_py_gen_aimrt_cpp_rpc/protoc_plugin_py_gen_aimrt_cpp_rpc.py index 94bbcc759..0bfaebc84 100755 --- a/src/tools/protoc_plugin_py_gen_aimrt_cpp_rpc/protoc_plugin_py_gen_aimrt_cpp_rpc.py +++ b/src/tools/protoc_plugin_py_gen_aimrt_cpp_rpc/protoc_plugin_py_gen_aimrt_cpp_rpc.py @@ -88,6 +88,7 @@ bool Register{{service_name}}ClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) class {{service_name}}SyncProxy : public aimrt::rpc::ProxyBase { public: explicit {{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}SyncProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -116,6 +117,7 @@ class {{service_name}}SyncProxy : public aimrt::rpc::ProxyBase { class {{service_name}}AsyncProxy : public aimrt::rpc::ProxyBase { public: explicit {{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}AsyncProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -147,6 +149,7 @@ class {{service_name}}AsyncProxy : public aimrt::rpc::ProxyBase { class {{service_name}}FutureProxy : public aimrt::rpc::ProxyBase { public: explicit {{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}FutureProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -175,6 +178,7 @@ class {{service_name}}FutureProxy : public aimrt::rpc::ProxyBase { class {{service_name}}CoProxy : public aimrt::rpc::CoProxyBase { public: explicit {{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{service_name}}CoProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -341,6 +345,10 @@ bool Register{{service_name}}ClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) {{for service begin}} {{service_name}}SyncProxy::{{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}SyncProxy::{{service_name}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} aimrt::rpc::Status {{service_name}}SyncProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, @@ -381,6 +389,10 @@ aimrt::rpc::Status {{service_name}}SyncProxy::{{rpc_func_name}}( {{for service begin}} {{service_name}}AsyncProxy::{{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}AsyncProxy::{{service_name}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} void {{service_name}}AsyncProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, @@ -418,6 +430,10 @@ void {{service_name}}AsyncProxy::{{rpc_func_name}}( {{for service begin}} {{service_name}}FutureProxy::{{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}FutureProxy::{{service_name}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} std::future {{service_name}}FutureProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, @@ -459,6 +475,10 @@ std::future {{service_name}}FutureProxy::{{rpc_func_name}}( {{for service begin}} {{service_name}}CoProxy::{{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::CoProxyBase(rpc_handle_ref, kRpcType, k{{service_name}}Name) {} + +{{service_name}}CoProxy::{{service_name}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::CoProxyBase(rpc_handle_ref, kRpcType, service_name) {} + {{for method begin}} aimrt::co::Task {{service_name}}CoProxy::{{rpc_func_name}}( aimrt::rpc::ContextRef ctx_ref, diff --git a/src/tools/ros2_py_gen_aimrt_cpp_rpc/ros2_py_gen_aimrt_cpp_rpc.py b/src/tools/ros2_py_gen_aimrt_cpp_rpc/ros2_py_gen_aimrt_cpp_rpc.py index d66c5b948..d274eaaff 100755 --- a/src/tools/ros2_py_gen_aimrt_cpp_rpc/ros2_py_gen_aimrt_cpp_rpc.py +++ b/src/tools/ros2_py_gen_aimrt_cpp_rpc/ros2_py_gen_aimrt_cpp_rpc.py @@ -83,6 +83,7 @@ bool Register{{srv_filename}}ClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) class {{srv_filename}}SyncProxy : public aimrt::rpc::ProxyBase { public: explicit {{srv_filename}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{srv_filename}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{srv_filename}}SyncProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -108,6 +109,7 @@ class {{srv_filename}}SyncProxy : public aimrt::rpc::ProxyBase { class {{srv_filename}}AsyncProxy : public aimrt::rpc::ProxyBase { public: explicit {{srv_filename}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{srv_filename}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{srv_filename}}AsyncProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -135,6 +137,7 @@ class {{srv_filename}}AsyncProxy : public aimrt::rpc::ProxyBase { class {{srv_filename}}FutureProxy : public aimrt::rpc::ProxyBase { public: explicit {{srv_filename}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{srv_filename}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{srv_filename}}FutureProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -160,6 +163,7 @@ class {{srv_filename}}FutureProxy : public aimrt::rpc::ProxyBase { class {{srv_filename}}CoProxy : public aimrt::rpc::CoProxyBase { public: explicit {{srv_filename}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref); + explicit {{srv_filename}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name); ~{{srv_filename}}CoProxy() = default; static bool RegisterClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) { @@ -314,6 +318,9 @@ bool Register{{srv_filename}}ClientFunc(aimrt::rpc::RpcHandleRef rpc_handle_ref) {{srv_filename}}SyncProxy::{{srv_filename}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, kServiceName) {} +{{srv_filename}}SyncProxy::{{srv_filename}}SyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + aimrt::rpc::Status {{srv_filename}}SyncProxy::{{srv_filename}}( aimrt::rpc::ContextRef ctx_ref, const {{srv_filename}}_Request& req, @@ -351,6 +358,9 @@ aimrt::rpc::Status {{srv_filename}}SyncProxy::{{srv_filename}}( {{srv_filename}}AsyncProxy::{{srv_filename}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, kServiceName) {} +{{srv_filename}}AsyncProxy::{{srv_filename}}AsyncProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + void {{srv_filename}}AsyncProxy::{{srv_filename}}( aimrt::rpc::ContextRef ctx_ref, const {{srv_filename}}_Request& req, @@ -385,6 +395,9 @@ void {{srv_filename}}AsyncProxy::{{srv_filename}}( {{srv_filename}}FutureProxy::{{srv_filename}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, kServiceName) {} +{{srv_filename}}FutureProxy::{{srv_filename}}FutureProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::ProxyBase(rpc_handle_ref, kRpcType, service_name) {} + std::future {{srv_filename}}FutureProxy::{{srv_filename}}( aimrt::rpc::ContextRef ctx_ref, const {{srv_filename}}_Request& req, @@ -423,6 +436,9 @@ std::future {{srv_filename}}FutureProxy::{{srv_filename}}( {{srv_filename}}CoProxy::{{srv_filename}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref) : aimrt::rpc::CoProxyBase(rpc_handle_ref, kRpcType, kServiceName) {} +{{srv_filename}}CoProxy::{{srv_filename}}CoProxy(aimrt::rpc::RpcHandleRef rpc_handle_ref, std::string_view service_name) + : aimrt::rpc::CoProxyBase(rpc_handle_ref, kRpcType, service_name) {} + aimrt::co::Task {{srv_filename}}CoProxy::{{srv_filename}}( aimrt::rpc::ContextRef ctx_ref, const {{srv_filename}}_Request& req, diff --git a/url_cn.bashrc b/url_cn.bashrc index 9ec2d746a..74df5d2c7 100644 --- a/url_cn.bashrc +++ b/url_cn.bashrc @@ -4,7 +4,7 @@ export AIMRT_DOWNLOAD_FLAGS="-Dboost_DOWNLOAD_URL=https://gitee.com/AimRT/boost/ -Dgoogletest_DOWNLOAD_URL=https://gitee.com/mirrors/googletest/repository/archive/v1.13.0.zip \ -Dprotobuf_DOWNLOAD_URL=https://gitee.com/mirrors/protobufsource/repository/archive/v3.21.12.zip \ -Dyaml-cpp_DOWNLOAD_URL=https://gitee.com/mirrors/yaml-cpp/repository/archive/0.8.0.zip \ - -Djsoncpp_DOWNLOAD_URL=https://gitee.com/mirrors/jsoncpp/repository/archive/1.9.5.zip \ + -Djsoncpp_DOWNLOAD_URL=https://gitee.com/mirrors/jsoncpp/repository/archive/1.9.6.zip \ -Dsqlite_DOWNLOAD_URL=https://gitee.com/AimRT/sqlite/releases/download/amalgamation-3420000/sqlite-amalgamation-3420000.zip \ -Dstdexec_DOWNLOAD_URL=https://gitee.com/AimRT/stdexec/repository/archive/nvhpc-23.09.rc4.zip \ -Dlibunifex_DOWNLOAD_URL=https://gitee.com/AimRT/libunifex/repository/archive/591ec09e7d51858ad05be979d4034574215f5971.zip \