Add const reference service callback signatures - #3269
KR-Ravindra wants to merge 1 commit into
Conversation
|
Round 1 self-review. Verified against
No duplicate: #3078 cross-references only this PR, and the approach is the one jmachowinski suggested there. Open #3168 touches the same |
fujitatomoya
left a comment
There was a problem hiding this comment.
lgtm with green CI. monor comment does not block this PR.
| } else if (std::holds_alternative<ConstRefCallback>(callback_)) { | ||
| const auto & cb = std::get<ConstRefCallback>(callback_); | ||
| cb(*request, *response); | ||
| } else if (std::holds_alternative<ConstRefWithRequestHeaderCallback>(callback_)) { | ||
| const auto & cb = std::get<ConstRefWithRequestHeaderCallback>(callback_); | ||
| cb(*request_header, *request, *response); |
There was a problem hiding this comment.
i would add assert(request_header) / assert(request) (or a throw std::runtime_error) before dereferencing just in case. this is different situation from shared pointer cases above.
There was a problem hiding this comment.
@fujitatomoya done in a90d9ca: dispatch() now throws std::runtime_error before dereferencing a null request or request_header in the two const-ref branches, matching the unset-callback check above, and test_any_service_callback.cpp gets a test for the null cases. Sorry this lands after you launched CI; the change is limited to those two branches. Could you take another look?
|
Pulls: #3269 |
AnyServiceCallback now also accepts void (const Request &, Response &) void (const rmw_request_id_t &, const Request &, Response &) in addition to the existing shared_ptr signatures. The request and response are still received as shared_ptr internally and are dereferenced before calling the user callback, mirroring what AnySubscriptionCallback does for const MessageT & callbacks. dispatch() throws std::runtime_error instead of dereferencing a null request or request header for these two alternatives. Both set() overloads gain matching function_traits::same_arguments branches so std::bind results resolve to the right alternative, and dispatch() handles the two new alternatives. Existing overloads are unchanged. Signed-off-by: KR Ravindra <42912207+KR-Ravindra@users.noreply.github.com>
e2c22d4 to
a90d9ca
Compare
Problem
AnySubscriptionCallbackacceptsconst MessageT &callbacks, butAnyServiceCallbackonly acceptsstd::shared_ptrsignatures. Every service callback therefore has to takeshared_ptrs (the response one is copied per call) even when the handler answers immediately and never needs to extend the request/response lifetime. This is inconsistent with subscriptions.Design
Follows the approach suggested in the issue: the request and response keep arriving as
shared_ptrinternally;dispatch()dereferences them for the user callback, exactly likeAnySubscriptionCallbackdoes forconst MessageT &. The existingshared_ptroverloads are unchanged.Fix
rclcpp/include/rclcpp/any_service_callback.hppConstRefCallback=void (const Request &, Response &)andConstRefWithRequestHeaderCallback=void (const rmw_request_id_t &, const Request &, Response &), appended after the existing alternatives.set()overloads get matchingfunction_traits::same_argumentsbranches sostd::bindresults resolve like theshared_ptrshapes do.dispatch()callscb(*request, *response)/cb(*request_header, *request, *response)and returns the response as before.The new alternatives cannot be ambiguous with the existing ones in the
std::variantconverting assignment: a callable takingconst Request &is not invocable with ashared_ptr<Request>and vice versa, so at most onestd::functionalternative is viable for any callback.How tested
rclcpp/test/rclcpp/test_any_service_callback.cpp: four new cases (const-ref without/with request header, response mutation propagated to the returnedshared_ptr,std::bindfor both shapes).rclcpp/test/rclcpp/test_service.cpp:create_service<>with a const-ref callback, exercised end to end through a client.Before the change, the new callback shapes fail to compile:
After the change the header compiles and all cases pass. I could not run
colcon testlocally (no ROS 2 workspace), so the new gtest cases were mirrored in a standalone gtest harness that compiles the unmodifiedany_service_callback.hpp/function_traits.hppagainst stubrmw/tracetoolsheaders: 10/10 pass with-Wall -Wextraon GCC 13, including the pre-existing callback shapes.cpplintwith the ament filters reports no issues. Please rely on CI for the full build and forament_uncrustify.Links
This change was prepared with an AI agent operated by KR-Ravindra, who reviewed and tested it.