Skip to content

JSON RPC 2.0 via MQTT#252

Merged
rovo89 merged 7 commits intomainfrom
feat/rpc
Oct 28, 2025
Merged

JSON RPC 2.0 via MQTT#252
rovo89 merged 7 commits intomainfrom
feat/rpc

Conversation

@rovo89
Copy link
Copy Markdown
Collaborator

@rovo89 rovo89 commented Oct 26, 2025

For more advanced cases of passing data to ROS (including method calls with parameters), let's use JSON RPC 2.0 over the existing MQTT connection.

Summary by CodeRabbit

  • New Features

    • Adds an RPC framework: remote method invocation with dynamic method registration, service to announce methods, introspection (list available methods), ping check, and standardized request/response/error topics.
  • Bug Fixes / Reliability

    • RPC provider retries method registration and handles JSON parsing and provider-side errors with propagated error responses.
  • Chores

    • Removes legacy action-based message types for action requests/responses.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 26, 2025

Walkthrough

Adds a new xbot_rpc package (msgs, srv, headers, provider, build manifests), integrates RPC into xbot_monitoring (deps, provider init, topics/services, request/response/error flow), and removes ActionRequest/ActionResponse message files and their generation from xbot_msgs.

Changes

Cohort / File(s) Summary
New xbot_rpc package config & build
src/lib/xbot_rpc/package.xml, src/lib/xbot_rpc/CMakeLists.txt
Add new catkin package manifest and CMake config (C++17, message/service generation, links nlohmann_json, builds/installs library and headers).
xbot_rpc public headers
src/lib/xbot_rpc/include/xbot_rpc/constants.h, src/lib/xbot_rpc/include/xbot_rpc/provider.h
Add RPC topic/service string constants and declare RpcProvider API, RpcException, callback_t typedef, and RPC_METHOD macro.
xbot_rpc implementation
src/lib/xbot_rpc/src/provider.cpp
Implement RpcProvider::init, publishMethods, handleRequest, publishResponse, publishError; handle JSON parsing, method dispatch, error publishing, and registration retries.
xbot_rpc msgs & service
src/lib/xbot_rpc/msg/RpcRequest.msg, src/lib/xbot_rpc/msg/RpcResponse.msg, src/lib/xbot_rpc/msg/RpcError.msg, src/lib/xbot_rpc/srv/RegisterMethodsSrv.srv
Add RpcRequest, RpcResponse, RpcError message definitions (with JSON-RPC error constants) and RegisterMethodsSrv service.
xbot_monitoring build & manifest changes
src/lib/xbot_monitoring/CMakeLists.txt, src/lib/xbot_monitoring/package.xml
Add xbot_rpc to build-time and runtime dependencies of xbot_monitoring.
xbot_monitoring RPC integration
src/lib/xbot_monitoring/src/xbot_monitoring.cpp
Wire RPC: switch to ordered_json, initialize RpcProvider, add /xbot/rpc/* publishers/subscribers, implement request/response/error callbacks, and expose register-methods service and local registry.
Removed message types
src/lib/xbot_msgs/CMakeLists.txt, src/lib/xbot_msgs/msg/ActionRequest.msg, src/lib/xbot_msgs/msg/ActionResponse.msg
Remove ActionRequest.msg and ActionResponse.msg from message generation and delete their definitions (fields removed).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect JSON parsing and JSON-RPC error mapping in src/lib/xbot_rpc/src/provider.cpp.
  • Verify thread-safety and correct locking around registered_methods in src/lib/xbot_monitoring/src/xbot_monitoring.cpp.
  • Confirm CMake/package targets correctly order message generation and link the xbot_rpc library.
  • Search codebase for remaining references to removed ActionRequest/ActionResponse message types.

Poem

🐰 I tunneled through topics, built a tiny RPC den,

I ping, I list, I parse with a hop and then a pen.
If JSON trips, I send a thoughtful shout,
Methods lined in burrows, ready to leap out.
Hop on the bus — the messages are in!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "JSON RPC 2.0 via MQTT" accurately and concisely describes the primary objective of the changeset. The PR introduces a comprehensive RPC implementation framework (xbot_rpc package) with JSON-RPC 2.0 message types, provider infrastructure, and integration into the xbot_monitoring system. The title correctly identifies this as implementing JSON RPC 2.0 over MQTT, matching the stated PR description to support method calls with parameters over the existing MQTT connection. The title is clear, specific, and avoids vague terminology.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/rpc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rovo89 rovo89 force-pushed the feat/rpc branch 2 times, most recently from 91cbec9 to 1ccf5cc Compare October 27, 2025 00:29
@rovo89 rovo89 marked this pull request as ready for review October 27, 2025 22:27
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Nitpick comments (9)
src/lib/xbot_rpc/srv/RegisterMethodsSrv.srv (1)

1-3: Consider adding a response field for registration confirmation.

The service currently has a void response. While this is valid, adding a boolean success field or a count of registered methods could improve observability and help callers verify successful registration.

Example enhancement:

 string node_id       # The ID of the node providing the methods.
 string[] methods     # The list of available methods.
 ---
+bool success         # Indicates whether registration succeeded.
+string message       # Optional status or error message.
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)

5-8: Use inline constexpr for header-only constants in C++17.

While static constexpr works, using inline constexpr is the modern C++17 best practice for header-only constants. This avoids potential ODR (One Definition Rule) issues and follows the C++ Core Guidelines.

Apply this diff:

-static constexpr const char* TOPIC_REQUEST = "/xbot/rpc/request";
-static constexpr const char* TOPIC_RESPONSE = "/xbot/rpc/response";
-static constexpr const char* TOPIC_ERROR = "/xbot/rpc/error";
-static constexpr const char* SERVICE_REGISTER_METHODS = "/xbot/rpc/register";
+inline constexpr const char* TOPIC_REQUEST = "/xbot/rpc/request";
+inline constexpr const char* TOPIC_RESPONSE = "/xbot/rpc/response";
+inline constexpr const char* TOPIC_ERROR = "/xbot/rpc/error";
+inline constexpr const char* SERVICE_REGISTER_METHODS = "/xbot/rpc/register";

Note: The static analysis errors shown are false positives from incomplete parsing and can be ignored.

src/lib/xbot_rpc/msg/RpcError.msg (1)

1-13: JSON‑RPC compatibility: id/data types

  • id is restricted to string; JSON‑RPC 2.0 allows string, number, or null. Either (a) document the string‑only deviation, or (b) support numbers by carrying id as string over ROS but preserving original type on the MQTT side.
  • data is a string here; ensure the MQTT bridge parses it back into JSON (see monitoring fixes below) to avoid double‑encoding.
src/lib/xbot_rpc/src/provider.cpp (2)

25-33: Improve registration robustness and observability.

Add waitForExistence and a final error after retries for better startup behavior and diagnostics.

   ros::Rate retry_delay(1);
   for (int i = 0; i < 10; i++) {
+    if (!registration_client.exists()) {
+      registration_client.waitForExistence(ros::Duration(1.0));
+    }
     if (registration_client.call(srv)) {
       ROS_INFO_STREAM("successfully registered methods for " << node_id);
       break;
     }
     ROS_ERROR_STREAM("Error registering methods for " << node_id << ". Retrying.");
     retry_delay.sleep();
   }
+  if (!registration_client.exists()) {
+    ROS_ERROR_STREAM("Failed to register methods for " << node_id << " after 10 attempts.");
+  }

43-52: Unify JSON type usage.

You parse into ordered_json but store in basic_json<>. Prefer consistent types to avoid template mismatches.

-  nlohmann::basic_json<> params;
+  nlohmann::ordered_json params;
   if (!request->params.empty()) {
     try {
-      params = nlohmann::ordered_json::parse(request->params);
+      params = nlohmann::ordered_json::parse(request->params);

Also consider updating callback_t in the header to ordered_json for consistency.

src/lib/xbot_rpc/include/xbot_rpc/provider.h (3)

12-14: Macro ergonomics.

RPC_METHOD is fine. Consider documenting that the first argument is the method id and the lambda receives (method, params) to avoid confusion.


17-19: Type clarity for JSON.

If provider uses ordered_json, align callback_t to ordered_json to avoid conversions.

-typedef std::function<nlohmann::basic_json<>(const std::string& topic, const nlohmann::basic_json<>& params)> callback_t;
+typedef std::function<nlohmann::ordered_json(const std::string& method,
+                                             const nlohmann::ordered_json& params)> callback_t;

20-29: Provide what() in RpcException.

Override what() so std::exception handling yields a meaningful message.

 class RpcException : public std::exception {
  public:
   const int16_t code;
   const std::string message;
   const nlohmann::basic_json<> data;

   RpcException(int16_t code, const std::string& message, const nlohmann::basic_json<>& data = nullptr)
       : code(code), message(message), data(data) {
   }
+  const char* what() const noexcept override { return message.c_str(); }
 };
src/lib/xbot_monitoring/src/xbot_monitoring.cpp (1)

595-636: Validation tweaks and robust id handling when building ROS message.

  • Avoid implicit json->string conversion; use getstd::string().
  • Optional: If you intend string‑only ids, keep validation as-is; otherwise support numeric/null and preserve type end‑to‑end (requires widening ROS message schema).
-    json id = req.contains("id") ? req["id"] : nullptr;
-    if (id != nullptr && !id.is_string()) {
+    json id = req.contains("id") ? req["id"] : nullptr;
+    if (id != nullptr && !id.is_string()) {
         return rpc_publish_error(xbot_rpc::RpcError::ERROR_INVALID_REQUEST, "ID is not a string", id);
     } else if (!req.contains("jsonrpc") || !req["jsonrpc"].is_string() || req["jsonrpc"] != "2.0") {
         return rpc_publish_error(xbot_rpc::RpcError::ERROR_INVALID_REQUEST, "Invalid JSON-RPC version");
     } else if (!req.contains("method") || !req["method"].is_string()) {
         return rpc_publish_error(xbot_rpc::RpcError::ERROR_INVALID_REQUEST, "Method is not a string", req["id"]);
     }
@@
-    msg.id = id != nullptr ? id : "";
+    msg.id = (id != nullptr) ? id.get<std::string>() : std::string();

Also guard registered_methods with the mutex during lookup:

-    bool is_registered = false;
-    for (const auto& [_, method_ids] : registered_methods) {
+    bool is_registered = false;
+    {
+      std::lock_guard<std::mutex> lk(registered_methods_mutex);
+      for (const auto& [_, method_ids] : registered_methods) {
         if (std::find(method_ids.begin(), method_ids.end(), method) != method_ids.end()) {
             is_registered = true;
             break;
         }
-    }
+      }
+    }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between beff72b and 7005625.

📒 Files selected for processing (15)
  • src/lib/xbot_monitoring/CMakeLists.txt (1 hunks)
  • src/lib/xbot_monitoring/package.xml (1 hunks)
  • src/lib/xbot_monitoring/src/xbot_monitoring.cpp (9 hunks)
  • src/lib/xbot_msgs/CMakeLists.txt (0 hunks)
  • src/lib/xbot_msgs/msg/ActionRequest.msg (0 hunks)
  • src/lib/xbot_msgs/msg/ActionResponse.msg (0 hunks)
  • src/lib/xbot_rpc/CMakeLists.txt (1 hunks)
  • src/lib/xbot_rpc/include/xbot_rpc/constants.h (1 hunks)
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h (1 hunks)
  • src/lib/xbot_rpc/msg/RpcError.msg (1 hunks)
  • src/lib/xbot_rpc/msg/RpcRequest.msg (1 hunks)
  • src/lib/xbot_rpc/msg/RpcResponse.msg (1 hunks)
  • src/lib/xbot_rpc/package.xml (1 hunks)
  • src/lib/xbot_rpc/src/provider.cpp (1 hunks)
  • src/lib/xbot_rpc/srv/RegisterMethodsSrv.srv (1 hunks)
💤 Files with no reviewable changes (3)
  • src/lib/xbot_msgs/msg/ActionRequest.msg
  • src/lib/xbot_msgs/CMakeLists.txt
  • src/lib/xbot_msgs/msg/ActionResponse.msg
🧰 Additional context used
🧬 Code graph analysis (3)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (1)
  • xbot_rpc (15-62)
src/lib/xbot_rpc/src/provider.cpp (1)
src/lib/xbot_monitoring/src/xbot_monitoring.cpp (2)
  • string (74-93)
  • string (74-74)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (2)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)
  • xbot_rpc (3-10)
src/lib/xbot_rpc/src/provider.cpp (10)
  • handleRequest (36-63)
  • handleRequest (36-36)
  • publishResponse (65-74)
  • publishResponse (65-66)
  • publishError (76-89)
  • publishError (76-77)
  • init (7-15)
  • init (7-7)
  • publishMethods (17-34)
  • publishMethods (17-17)
🪛 Clang (14.0.6)
src/lib/xbot_rpc/include/xbot_rpc/constants.h

[error] 3-3: unknown type name 'namespace'

(clang-diagnostic-error)


[error] 3-3: expected ';' after top level declarator

(clang-diagnostic-error)

src/lib/xbot_rpc/src/provider.cpp

[error] 1-1: 'xbot_rpc/provider.h' file not found

(clang-diagnostic-error)

src/lib/xbot_rpc/include/xbot_rpc/provider.h

[error] 3-3: 'ros/ros.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, legacy, ./docker/Dockerfile.Legacy)
  • GitHub Check: build (ubuntu-24.04, amd64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04, amd64, legacy, ./docker/Dockerfile.Legacy)
🔇 Additional comments (8)
src/lib/xbot_rpc/package.xml (1)

1-23: LGTM!

The package manifest is well-structured and includes all required dependencies for a ROS package with message generation.

src/lib/xbot_monitoring/package.xml (1)

25-25: LGTM!

The xbot_rpc dependency is correctly added using the <depend> tag, which covers build, export, and runtime requirements.

src/lib/xbot_monitoring/CMakeLists.txt (1)

16-16: LGTM!

The xbot_rpc component is correctly added to the catkin build dependencies, consistent with the package.xml changes.

src/lib/xbot_rpc/src/provider.cpp (1)

76-89: Guard optional error data correctly.

data != nullptr is fine for nlohmann::json. Keep as-is.

Please verify downstream (monitoring) parses err_msg.data back into JSON before publishing to MQTT to avoid double‑encoding (see my comment on rpc_error_callback).

src/lib/xbot_rpc/include/xbot_rpc/provider.h (1)

41-45: Visibility of publishMethods.

publishMethods is already public below; avoid duplicate declarations if any arise during future merges.

src/lib/xbot_monitoring/src/xbot_monitoring.cpp (3)

123-126: OK: Forwarding MQTT RPC requests into local handler.

Looks good.


638-648: Result parsing and error propagation: OK.

Good fallback to publish an internal error with the raw result on parse failure.

Consider logging the offending provider node/method for easier tracing.


702-706: RPC wiring: LGTM.

Good: publishers/subscribers and service advertised before provider.init().

Comment thread src/lib/xbot_monitoring/src/xbot_monitoring.cpp
Comment thread src/lib/xbot_monitoring/src/xbot_monitoring.cpp
Comment thread src/lib/xbot_monitoring/src/xbot_monitoring.cpp Outdated
Comment thread src/lib/xbot_monitoring/src/xbot_monitoring.cpp
Comment thread src/lib/xbot_monitoring/src/xbot_monitoring.cpp
Comment thread src/lib/xbot_rpc/CMakeLists.txt Outdated
Comment thread src/lib/xbot_rpc/include/xbot_rpc/provider.h Outdated
Comment thread src/lib/xbot_rpc/msg/RpcRequest.msg
Comment thread src/lib/xbot_rpc/msg/RpcResponse.msg
Comment thread src/lib/xbot_rpc/src/provider.cpp
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (2)

10-10: Prefer package-qualified include for portability.

Using "constants.h" (local include) may fail when this header is included from other packages. Package-qualified includes are more robust.

Apply this diff:

-#include "constants.h"
+#include <xbot_rpc/constants.h>

3-11: Add standard library includes for self-containment.

The header uses standard types but relies on transitive includes. Adding direct includes prevents breakage if dependencies change their includes.

Apply this diff:

 #pragma once
 
+#include <cstdint>
+#include <exception>
+#include <functional>
+#include <map>
+#include <string>
+#include <utility>
+
 #include <ros/ros.h>
 #include <xbot_rpc/RpcError.h>
 #include <xbot_rpc/RpcRequest.h>
 #include <xbot_rpc/RpcResponse.h>
 
 #include <nlohmann/json.hpp>
 
-#include "constants.h"
+#include <xbot_rpc/constants.h>
src/lib/xbot_monitoring/src/xbot_monitoring.cpp (1)

655-657: Parse serialized JSON before forwarding to MQTT.

The msg->data field contains a JSON-serialized string (from provider.cpp:86). Passing it directly to rpc_publish_error causes double-encoding, embedding escaped JSON as a string value instead of an object.

Apply this diff to parse the data:

 void rpc_error_callback(const xbot_rpc::RpcError::ConstPtr &msg) {
-    rpc_publish_error(msg->code, msg->message, msg->id, msg->data);
+    json id = msg->id.empty() ? nullptr : json(msg->id);
+    if (!msg->data.empty()) {
+        try {
+            json data = json::parse(msg->data);
+            rpc_publish_error(msg->code, msg->message, id, data);
+        } catch (const json::parse_error&) {
+            // On parse failure, omit data or use string as fallback
+            rpc_publish_error(msg->code, msg->message, id);
+        }
+    } else {
+        rpc_publish_error(msg->code, msg->message, id);
+    }
 }

Based on learnings

🧹 Nitpick comments (1)
src/lib/xbot_rpc/src/provider.cpp (1)

60-60: Prefer const reference for read-only exception.

Catching by non-const reference when only reading is unconventional.

Apply this diff:

-  } catch (std::exception& e) {
+  } catch (const std::exception& e) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7005625 and 542be5a.

📒 Files selected for processing (5)
  • src/lib/xbot_monitoring/src/xbot_monitoring.cpp (9 hunks)
  • src/lib/xbot_rpc/CMakeLists.txt (1 hunks)
  • src/lib/xbot_rpc/include/xbot_rpc/constants.h (1 hunks)
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h (1 hunks)
  • src/lib/xbot_rpc/src/provider.cpp (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/xbot_rpc/CMakeLists.txt
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.
📚 Learning: 2025-10-27T23:20:49.624Z
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.

Applied to files:

  • src/lib/xbot_rpc/include/xbot_rpc/constants.h
  • src/lib/xbot_monitoring/src/xbot_monitoring.cpp
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h
🧬 Code graph analysis (3)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (1)
  • xbot_rpc (15-33)
src/lib/xbot_rpc/src/provider.cpp (1)
src/lib/xbot_monitoring/src/xbot_monitoring.cpp (2)
  • string (75-94)
  • string (75-75)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (2)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)
  • xbot_rpc (3-10)
src/lib/xbot_rpc/src/provider.cpp (10)
  • handleRequest (36-63)
  • handleRequest (36-36)
  • publishResponse (65-74)
  • publishResponse (65-66)
  • publishError (76-89)
  • publishError (76-77)
  • init (7-15)
  • init (7-7)
  • publishMethods (17-34)
  • publishMethods (17-17)
🪛 Clang (14.0.6)
src/lib/xbot_rpc/include/xbot_rpc/constants.h

[error] 3-3: unknown type name 'namespace'

(clang-diagnostic-error)


[error] 3-3: expected ';' after top level declarator

(clang-diagnostic-error)

src/lib/xbot_rpc/src/provider.cpp

[error] 1-1: 'xbot_rpc/provider.h' file not found

(clang-diagnostic-error)

src/lib/xbot_rpc/include/xbot_rpc/provider.h

[error] 3-3: 'ros/ros.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (ubuntu-24.04, amd64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04, amd64, legacy, ./docker/Dockerfile.Legacy)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, legacy, ./docker/Dockerfile.Legacy)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, default, ./docker/Dockerfile)
🔇 Additional comments (15)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)

1-10: LGTM!

The constants header is well-structured. The use of inline constexpr const char* ensures no ODR violations while providing compile-time constant strings for RPC topic and service names.

src/lib/xbot_rpc/src/provider.cpp (4)

7-15: LGTM!

The initialization properly sets up the ROS communication infrastructure with appropriate queue sizes. The use of tcpNoDelay(true) is beneficial for RPC latency.


17-34: LGTM!

The retry logic is sensible for service registration during node startup. The structured binding with _ for the unused callback value is idiomatic C++17.


65-74: LGTM!

Correctly implements JSON-RPC 2.0 notification semantics by suppressing responses when id is empty.


76-89: LGTM!

The error publishing logic properly handles optional error data and respects JSON-RPC 2.0 notification semantics.

src/lib/xbot_rpc/include/xbot_rpc/provider.h (3)

12-13: LGTM!

The macro provides convenient method registration syntax. The lambda captures align with the callback_t signature and the brace-enclosed body allows multi-statement implementations.


17-18: LGTM!

The callback signature is appropriate for RPC handlers, taking method name and parameters as const references and returning a JSON result.


20-33: LGTM!

The exception class follows best practices: const members prevent mutation, proper inheritance from std::exception, and noexcept on what() satisfies the standard contract.

src/lib/xbot_monitoring/src/xbot_monitoring.cpp (7)

30-30: LGTM!

Switching to ordered_json ensures consistent key ordering in MQTT payloads, which can be beneficial for debugging and testing.


42-44: LGTM!

The mutex properly protects the registered_methods map from concurrent access between MQTT callbacks and ROS service handlers, addressing the data race concern.


142-157: LGTM!

The RPC provider initialization includes built-in introspection methods. The rpc.methods handler properly locks the registered_methods map during iteration and provides sorted output for consistency.


597-641: LGTM!

The request handler implements comprehensive JSON-RPC 2.0 validation and properly synchronizes access to registered_methods during method lookup. The forwarding to ROS correctly serializes parameters and handles optional request IDs.


643-653: LGTM!

The response handler correctly parses the serialized result JSON before constructing the MQTT response, avoiding double-encoding. The error handling for parse failures is appropriate.


659-664: LGTM!

The service handler correctly protects the write to registered_methods with the mutex, ensuring thread-safe registration.


708-716: LGTM!

The RPC infrastructure is properly wired during initialization. Publishers, subscribers, and service server are created with appropriate queue sizes, and the provider is initialized after all ROS communication channels are established.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (1)

1-10: Header still not self-contained.

The header uses std::string, std::map, std::function, and int16_t but doesn't explicitly include their headers (<string>, <map>, <functional>, <cstdint>). While ros/ros.h may transitively provide these, the header should not rely on transitive includes.

Apply this diff to make the header self-contained:

 #pragma once
 
+#include <cstdint>
+#include <functional>
+#include <map>
+#include <string>
+
 #include <ros/ros.h>
 #include <xbot_rpc/RpcError.h>
 #include <xbot_rpc/RpcRequest.h>
 #include <xbot_rpc/RpcResponse.h>
 #include <xbot_rpc/constants.h>
 
 #include <nlohmann/json.hpp>
src/lib/xbot_monitoring/src/xbot_monitoring.cpp (1)

652-654: Consider future-proofing for the optional data field.

The current implementation works correctly because provider.cpp never sets the data field of RpcError (it remains empty). However, if future code does populate it, the data would need to be parsed from string to JSON to avoid double-encoding in the MQTT response, similar to how msg->result is handled in rpc_response_callback.

If you want to future-proof this, you could add handling for the data field:

 void rpc_error_callback(const xbot_rpc::RpcError::ConstPtr &msg) {
-    rpc_publish_error(msg->code, msg->message, msg->id);
+    json id = msg->id.empty() ? nullptr : json(msg->id);
+    // Currently data is always empty, but parse it if present for future extensibility
+    json data = nullptr;
+    if (!msg->data.empty()) {
+        try {
+            data = json::parse(msg->data);
+        } catch (...) {
+            // If parse fails, include raw string
+            data = msg->data;
+        }
+    }
+    json err_resp = {{"jsonrpc", "2.0"},
+                     {"error", {{"code", msg->code}, {"message", msg->message}}},
+                     {"id", id}};
+    if (data != nullptr) {
+        err_resp["error"]["data"] = data;
+    }
+    try_publish("rpc/response", err_resp.dump(2));
 }

Note: This would also require updating the rpc_publish_error signature to accept optional data, or handling it inline as shown above.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 542be5a and 5f19964.

📒 Files selected for processing (3)
  • src/lib/xbot_monitoring/src/xbot_monitoring.cpp (9 hunks)
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h (1 hunks)
  • src/lib/xbot_rpc/src/provider.cpp (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.
📚 Learning: 2025-10-27T23:20:49.624Z
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.

Applied to files:

  • src/lib/xbot_monitoring/src/xbot_monitoring.cpp
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h
🧬 Code graph analysis (2)
src/lib/xbot_rpc/src/provider.cpp (1)
src/lib/xbot_monitoring/src/xbot_monitoring.cpp (2)
  • string (75-94)
  • string (75-75)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (2)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)
  • xbot_rpc (3-10)
src/lib/xbot_rpc/src/provider.cpp (10)
  • handleRequest (36-63)
  • handleRequest (36-36)
  • publishResponse (65-74)
  • publishResponse (65-66)
  • publishError (76-85)
  • publishError (76-76)
  • init (7-15)
  • init (7-7)
  • publishMethods (17-34)
  • publishMethods (17-17)
🪛 Clang (14.0.6)
src/lib/xbot_rpc/src/provider.cpp

[error] 1-1: 'xbot_rpc/provider.h' file not found

(clang-diagnostic-error)

src/lib/xbot_rpc/include/xbot_rpc/provider.h

[error] 3-3: 'ros/ros.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (ubuntu-24.04, amd64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04, amd64, legacy, ./docker/Dockerfile.Legacy)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, legacy, ./docker/Dockerfile.Legacy)
🔇 Additional comments (16)
src/lib/xbot_rpc/src/provider.cpp (4)

7-15: LGTM! Initialization logic is correct.

The queue size issue from the previous review has been addressed. The initialization properly sets up all ROS communication channels and triggers method registration.


17-34: LGTM! Retry logic is appropriate.

The 10-retry limit with 1-second delays provides a reasonable grace period for the registration service to become available during system startup.


36-63: LGTM! Request handling is robust.

The implementation correctly:

  • Silently ignores requests for unregistered methods (allowing multiple providers to coexist)
  • Validates JSON parameter syntax before execution
  • Catches both RpcException and generic exceptions
  • Maps exceptions to appropriate JSON-RPC error codes

65-85: LGTM! Response and error handling follows JSON-RPC 2.0 spec.

Both methods correctly check for empty request IDs to avoid responding to notifications. The RpcError message's optional data field is intentionally left empty in this implementation, which is valid per JSON-RPC 2.0.

src/lib/xbot_rpc/include/xbot_rpc/provider.h (3)

11-17: LGTM! Macro and typedef provide clean registration API.

The RPC_METHOD macro elegantly creates inline method registrations, and the callback_t typedef clearly documents the callback signature.


19-31: LGTM! Exception class is correctly designed.

The RpcException properly inherits from std::exception and provides both structured error information (code, message) and the standard what() interface.


33-61: LGTM! Provider class has a clean public API.

The class provides:

  • Constructor with optional initial methods
  • Initialization to set up ROS communication
  • Method registration (individual or batch)
  • Automatic method publishing to the registry

The private implementation details are appropriately hidden.

src/lib/xbot_monitoring/src/xbot_monitoring.cpp (9)

17-17: LGTM! Includes and type alias are appropriate.

The includes bring in the necessary RPC infrastructure, and using ordered_json ensures deterministic JSON output which is helpful for testing and debugging.

Also applies to: 23-28, 30-30


42-44: LGTM! RPC state management is thread-safe.

The registered_methods map is properly protected by a mutex, addressing concurrency concerns from the previous review. The publisher declaration is straightforward.

Also applies to: 62-62


93-93: LGTM! MQTT-to-RPC routing is correct.

The subscription to the rpc/request topic and the routing logic in the message handler properly integrate RPC into the MQTT callback flow.

Also applies to: 124-127


142-157: LGTM! Built-in RPC methods are correctly implemented.

The rpc.ping and rpc.methods methods follow JSON-RPC conventions. The mutex is correctly held while iterating registered_methods to prevent concurrent modification.


587-592: LGTM! Error response helper follows JSON-RPC 2.0.

The function correctly constructs JSON-RPC 2.0 error responses with the required jsonrpc, error, and id fields.


594-638: LGTM! Request validation and routing is thorough.

The implementation correctly:

  • Validates JSON syntax and structure
  • Checks JSON-RPC 2.0 version and required fields
  • Verifies the requested method is registered (with proper locking)
  • Forwards valid requests to providers via ROS
  • Returns appropriate error codes for each failure mode

640-650: LGTM! Response handling correctly deserializes the result.

The implementation properly parses msg->result (which arrives as a JSON string from the provider) back into a JSON value before embedding it in the JSON-RPC response. This is the correct approach—the result field should be a JSON value, not a double-encoded string.

Based on learnings: This follows the established pattern where xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.


656-661: LGTM! Method registration is thread-safe.

The mutex correctly protects the registered_methods update, addressing the concurrency concern from the previous review.


705-708: LGTM! RPC integration wiring is complete.

The setup properly:

  • Creates the ROS publisher for forwarding requests
  • Subscribes to response and error topics
  • Advertises the registration service
  • Initializes the provider to register built-in methods

Also applies to: 713-713

We probably won't need it and it would require even more complexity than we already had (to decode the JSON in xbot_monitoring if necessary).
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/lib/xbot_rpc/src/provider.cpp (1)

18-28: Consider retry logic or better error handling for method registration.

If the registration service call fails, the provider's methods won't be discoverable by clients, but the provider continues silently. Consider either implementing retry logic with exponential backoff or surfacing the registration failure to the caller.

Example with simple retry:

 void RpcProvider::publishMethods() {
+  const int max_attempts = 3;
+  for (int attempt = 1; attempt <= max_attempts; ++attempt) {
     xbot_rpc::RegisterMethodsSrv srv;
     srv.request.node_id = node_id;
     srv.request.methods.reserve(methods.size());
     for (const auto& [method_id, _] : methods) {
       srv.request.methods.push_back(method_id);
     }
-    if (!registration_client.call(srv)) {
-      ROS_ERROR_STREAM("Error registering methods for " << node_id);
+    if (registration_client.call(srv)) {
+      return;
+    }
+    if (attempt < max_attempts) {
+      ROS_WARN_STREAM("Failed to register methods for " << node_id << ", attempt " << attempt << "/" << max_attempts);
+      ros::Duration(1.0).sleep();
+    } else {
+      ROS_ERROR_STREAM("Failed to register methods for " << node_id << " after " << max_attempts << " attempts");
     }
+  }
 }
src/lib/xbot_rpc/include/xbot_rpc/provider.h (1)

11-12: Rename parameter from "topic" to "method" for clarity.

The first parameter of the callback is the method name (as seen in provider.cpp line 50 where it's called with request->method), not a topic. The parameter name "topic" is misleading.

-#define RPC_METHOD(id, body) \
-  { id, [](const std::string& topic, const nlohmann::basic_json<>& params) body }
+#define RPC_METHOD(id, body) \
+  { id, [](const std::string& method, const nlohmann::basic_json<>& params) body }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f19964 and 559262e.

📒 Files selected for processing (4)
  • src/lib/xbot_monitoring/src/xbot_monitoring.cpp (9 hunks)
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h (1 hunks)
  • src/lib/xbot_rpc/msg/RpcError.msg (1 hunks)
  • src/lib/xbot_rpc/src/provider.cpp (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.
📚 Learning: 2025-10-27T23:20:49.624Z
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.

Applied to files:

  • src/lib/xbot_monitoring/src/xbot_monitoring.cpp
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h
🧬 Code graph analysis (2)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (2)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)
  • xbot_rpc (3-10)
src/lib/xbot_rpc/src/provider.cpp (10)
  • handleRequest (30-57)
  • handleRequest (30-30)
  • publishResponse (59-68)
  • publishResponse (59-60)
  • publishError (70-79)
  • publishError (70-70)
  • init (7-16)
  • init (7-7)
  • publishMethods (18-28)
  • publishMethods (18-18)
src/lib/xbot_rpc/src/provider.cpp (1)
src/lib/xbot_monitoring/src/xbot_monitoring.cpp (2)
  • string (75-94)
  • string (75-75)
🪛 Clang (14.0.6)
src/lib/xbot_rpc/include/xbot_rpc/provider.h

[error] 3-3: 'ros/ros.h' file not found

(clang-diagnostic-error)

src/lib/xbot_rpc/src/provider.cpp

[error] 1-1: 'xbot_rpc/provider.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04, amd64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04, amd64, legacy, ./docker/Dockerfile.Legacy)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, legacy, ./docker/Dockerfile.Legacy)
🔇 Additional comments (15)
src/lib/xbot_rpc/msg/RpcError.msg (2)

1-3: LGTM!

The core error message fields are correctly defined for JSON-RPC 2.0 error responses.


5-12: LGTM!

The error code constants correctly match the JSON-RPC 2.0 specification, and the comments provide clear descriptions.

src/lib/xbot_rpc/src/provider.cpp (4)

7-16: LGTM!

The initialization properly sets up ROS communication with appropriate queue sizes and the 10-second service wait provides reasonable startup behavior.


30-57: LGTM!

The request handling logic is solid: it correctly ignores unknown methods (allowing multiple providers), handles JSON parsing errors, executes callbacks, and catches both custom and standard exceptions with appropriate error responses.


59-68: LGTM!

Correctly implements JSON-RPC 2.0 response handling by only publishing responses for requests with an id (notifications don't get responses).


70-79: LGTM!

Error publishing correctly follows JSON-RPC 2.0 by only sending errors for requests with an id.

src/lib/xbot_rpc/include/xbot_rpc/provider.h (2)

19-31: LGTM!

The RpcException class provides a clean way to signal RPC errors with both a code and message, properly inheriting from std::exception.


33-61: LGTM!

The RpcProvider class is well-structured with appropriate encapsulation. Note that init() must be called after construction to set up ROS communication.

src/lib/xbot_monitoring/src/xbot_monitoring.cpp (7)

23-30: LGTM!

The switch to ordered_json ensures consistent JSON output ordering, which is helpful for testing and debugging.


42-44: LGTM!

The registered_methods map is properly protected with a mutex for thread-safe access between MQTT and ROS callbacks.

Also applies to: 62-62


142-157: LGTM!

The built-in RPC methods provide essential functionality: rpc.ping for health checks and rpc.methods for method discovery. The mutex protection in rpc.methods is correct.


587-592: LGTM!

The function correctly formats JSON-RPC 2.0 error responses for MQTT clients, including the required "jsonrpc" field at the protocol boundary. Based on learnings.


640-650: LGTM!

The response callback correctly parses the serialized JSON result from the ROS message and formats it as a proper JSON-RPC 2.0 response for MQTT clients.


652-661: LGTM!

Both callbacks correctly handle their respective flows: forwarding errors to MQTT and registering methods with proper mutex protection.


705-708: LGTM!

The RPC infrastructure is properly initialized with consistent queue sizes and the provider is initialized after ROS node setup.

Also applies to: 713-713

Comment thread src/lib/xbot_monitoring/src/xbot_monitoring.cpp
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (1)

3-9: Standard headers still missing (partial fix from previous review).

While line 7 correctly fixed the constants.h include path, the header still lacks explicit includes for standard types it uses directly. Relying on transitive includes from ros/ros.h is brittle.

Add the following includes after line 6:

 #include <xbot_rpc/RpcResponse.h>
 #include <xbot_rpc/constants.h>
+#include <cstdint>
+#include <exception>
+#include <functional>
+#include <map>
+#include <string>
+#include <utility>

 #include <nlohmann/json.hpp>
🧹 Nitpick comments (1)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (1)

47-47: Consider move semantics for the constructor parameter.

The constructor copies the methods map. For better performance with large method registries, consider accepting the map by value and moving it.

-  RpcProvider(const std::string& node_id, const std::map<std::string, callback_t>& methods = {}) : node_id(node_id), methods(methods) {}
+  RpcProvider(const std::string& node_id, std::map<std::string, callback_t> methods = {}) 
+      : node_id(node_id), methods(std::move(methods)) {}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 559262e and d244199.

📒 Files selected for processing (1)
  • src/lib/xbot_rpc/include/xbot_rpc/provider.h (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.
📚 Learning: 2025-10-27T23:20:49.624Z
Learnt from: rovo89
PR: ClemensElflein/open_mower_ros#252
File: src/lib/xbot_rpc/msg/RpcRequest.msg:1-3
Timestamp: 2025-10-27T23:20:49.624Z
Learning: In the open_mower_ros xbot_rpc system, the xbot_monitoring node acts as the JSON-RPC 2.0 gateway between MQTT and internal ROS messaging. The RpcRequest.msg, RpcResponse.msg, and RpcError.msg are internal ROS message formats and do not need to include the "jsonrpc" field because xbot_monitoring handles JSON-RPC 2.0 protocol compliance at the MQTT boundary.

Applied to files:

  • src/lib/xbot_rpc/include/xbot_rpc/provider.h
🧬 Code graph analysis (1)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (2)
src/lib/xbot_rpc/include/xbot_rpc/constants.h (1)
  • xbot_rpc (3-10)
src/lib/xbot_rpc/src/provider.cpp (10)
  • handleRequest (30-57)
  • handleRequest (30-30)
  • publishResponse (59-68)
  • publishResponse (59-60)
  • publishError (70-79)
  • publishError (70-70)
  • init (7-16)
  • init (7-7)
  • publishMethods (18-28)
  • publishMethods (18-18)
🪛 Clang (14.0.6)
src/lib/xbot_rpc/include/xbot_rpc/provider.h

[error] 3-3: 'ros/ros.h' file not found

(clang-diagnostic-error)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (ubuntu-24.04, amd64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04, amd64, legacy, ./docker/Dockerfile.Legacy)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, default, ./docker/Dockerfile)
  • GitHub Check: build (ubuntu-24.04-arm, arm64, legacy, ./docker/Dockerfile.Legacy)
🔇 Additional comments (3)
src/lib/xbot_rpc/include/xbot_rpc/provider.h (3)

11-12: Convenience macro design is sound.

The RPC_METHOD macro provides a clean initializer syntax for registering handlers. The limitation that lambdas cannot capture variables is acceptable—users can manually define lambdas with captures when needed.


18-30: Exception class design is clean and correct.

The RpcException design properly inherits from std::exception, uses const members for immutability, and correctly implements what() with noexcept. Public access to code and message is appropriate for a simple exception type.


51-57: addMethod overloads are well-designed.

Both overloads use appropriate insertion methods: emplace for constructing in-place from separate arguments, and insert for an existing pair. The design provides flexibility for users.

@rovo89 rovo89 merged commit 5177894 into main Oct 28, 2025
6 checks passed
@rovo89 rovo89 deleted the feat/rpc branch October 28, 2025 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant