Class OperationManager

Class Documentation

class OperationManager

Application service for ROS 2 service / action operations.

Pure C++; ROS-side I/O is performed by the injected ServiceTransport and ActionTransport adapters. Goal tracking, UUID generation, type validation and component-namespace resolution remain in the manager body.

Public Types

using LogSink = std::function<void(int level, std::string_view message)>

Sink for internal diagnostics (stuck-goal eviction, etc.). Keeps OperationManager middleware-neutral while preserving observability when the gateway adapter forwards to /rosout. May be null - the sink is then a no-op, which is the production behaviour today.

Public Functions

OperationManager(std::shared_ptr<ServiceTransport> service_transport, std::shared_ptr<ActionTransport> action_transport, ServiceActionResolver *resolver, int service_call_timeout_sec = 10, LogSink log_sink = nullptr)
Parameters:
  • service_transport – Concrete ServiceTransport adapter (typically Ros2ServiceTransport).

  • action_transport – Concrete ActionTransport adapter (typically Ros2ActionTransport).

  • resolver – Service / action lookup interface (DiscoveryManager implements it). Must outlive this manager. May be nullptr in tests that do not exercise the component-name resolution paths.

  • service_call_timeout_sec – Timeout in seconds applied to every service / action call.

  • log_sink – Optional sink for internal diagnostics. Pass nullptr to silence stuck-goal eviction warnings (default).

~OperationManager()
OperationManager(const OperationManager&) = delete
OperationManager &operator=(const OperationManager&) = delete
OperationManager(OperationManager&&) = delete
OperationManager &operator=(OperationManager&&) = delete
void shutdown()

Idempotent teardown. Clears tracked goals and unsubscribes from status topics. Subsequent calls are no-ops. Transport teardown is owned by the transport destructors.

void set_notifier(ResourceChangeNotifier *notifier)

Set optional notifier for broadcasting operation status changes to trigger subsystem.

ServiceCallResult call_service(const std::string &service_path, const std::string &service_type, const json &request)

Call a ROS 2 service synchronously through the ServiceTransport.

ServiceCallResult call_component_service(const std::string &component_ns, const std::string &operation_name, const std::optional<std::string> &service_type, const json &request)

Find and call a service by component and operation name. Resolves the path / type via the ServiceActionResolver when type is unset.

ActionSendGoalResult send_action_goal(const std::string &action_path, const std::string &action_type, const json &goal, const std::string &entity_id = "")

Send a goal to an action server through the ActionTransport.

ActionSendGoalResult send_component_action_goal(const std::string &component_ns, const std::string &operation_name, const std::optional<std::string> &action_type, const json &goal, const std::string &entity_id = "")

Send a goal using component namespace + operation name. Resolves through the ServiceActionResolver when type is unset.

ActionCancelResult cancel_action_goal(const std::string &action_path, const std::string &goal_id)

Cancel a running action goal.

ActionGetResultResult get_action_result(const std::string &action_path, const std::string &action_type, const std::string &goal_id)

Get the result of a completed action.

std::optional<ActionGoalInfo> get_tracked_goal(const std::string &goal_id) const

Get tracked goal info by goal_id.

std::vector<ActionGoalInfo> list_tracked_goals() const

List all tracked goals.

std::vector<ActionGoalInfo> get_goals_for_action(const std::string &action_path) const

Get all goals for a specific action path, sorted by created_at (newest first).

std::optional<ActionGoalInfo> get_latest_goal_for_action(const std::string &action_path) const

Get the most recent goal for a specific action path.

void update_goal_status(const std::string &goal_id, ActionGoalStatus status)

Update goal status in tracking. No-op if the goal is unknown.

void update_goal_feedback(const std::string &goal_id, const json &feedback)

Update goal feedback in tracking. No-op if the goal is unknown.

void cleanup_old_goals(std::chrono::seconds max_age = std::chrono::seconds(300))

Remove completed goals older than max_age. Forwards the unsubscribe request to the action transport for each path that becomes empty.

void subscribe_to_action_status(const std::string &action_path)

Subscribe (idempotently) to action status updates. Wires the transport callback into update_goal_status() so external status changes update the tracking map on the transport’s executor thread.

void unsubscribe_from_action_status(const std::string &action_path)

Unsubscribe from action status updates. Idempotent.

void inject_tracked_goal_for_testing(ActionGoalInfo info)

Test-only helper: inject a fully-formed ActionGoalInfo directly into the tracking map. Used by unit tests to exercise paths (e.g. stuck-goal eviction) without driving real action server traffic. Not part of the production API.

Public Static Functions

static bool is_valid_message_type(const std::string &type)

Validate message type format (package/srv/Type or package/action/Type or package/msg/Type).

static bool is_valid_uuid_hex(const std::string &uuid_hex)

Validate UUID hex string format (32 hex characters).

static bool is_service_type(const std::string &type)

Check if type is a service type (contains /srv/).

static bool is_action_type(const std::string &type)

Check if type is an action type (contains /action/).

Public Static Attributes

static constexpr int kLogLevelWarn = 30

Severity used by the OperationManager’s log_sink callback. Numeric values match rcl/rcutils log levels (30=WARN, 40=ERROR) so an adapter can forward to RCLCPP_* macros without translation. Mirrors LogManager’s kLogLevelWarn / kLogLevelError contract.

static constexpr int kLogLevelError = 40