From 2c52767b74ea2fab8579aad7c911d9e2ea8f0549 Mon Sep 17 00:00:00 2001 From: "Minju, Lee" Date: Tue, 25 Jun 2024 21:29:14 +0900 Subject: [PATCH] add: get clients, servers info Signed-off-by: Minju, Lee --- rmw/include/rmw/get_topic_endpoint_info.h | 160 ++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/rmw/include/rmw/get_topic_endpoint_info.h b/rmw/include/rmw/get_topic_endpoint_info.h index 8e873b87..449b0b80 100644 --- a/rmw/include/rmw/get_topic_endpoint_info.h +++ b/rmw/include/rmw/get_topic_endpoint_info.h @@ -186,6 +186,166 @@ rmw_get_subscriptions_info_by_topic( bool no_mangle, rmw_topic_endpoint_info_array_t * subscriptions_info); +/// Retrieve endpoint information for each known client of a given service. +/** + * This function returns an array of endpoint information for each client + * of a given service, as discovered so far by the given node. + * Endpoint information includes the client's node name and namespace, + * the associated topic type, the client's gid, and the client QoS profile. + * Names of non-existent topics are allowed, in which case an empty array will be returned. + * + * Depending on the RMW in use, discovery may be asynchronous. Therefore, creating a client + * and then calling this API may not show the newly created client immediately. + * + * \par QoS that are correctly read + * Not all QoS may be read correctly, \sa rmw_get_publishers_info_by_topic() for more details. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | Yes + * Uses Atomics | Maybe [1] + * Lock-Free | Maybe [1] + * [1] rmw implementation defined, check the implementation documentation + * + * \par Runtime behavior + * To query the ROS graph is a synchronous operation. + * It is also non-blocking, but it is not guaranteed to be lock-free. + * Generally speaking, implementations may synchronize access to internal resources using + * locks but are not allowed to wait for events with no guaranteed time bound (barring + * the effects of starvation due to OS scheduling). + * + * \par Thread-safety + * Nodes are thread-safe objects, and so are all operations on them except for finalization. + * Therefore, it is safe to query the ROS graph using the same node concurrently. + * However, when querying service names and types: + * - Access to the array of topic endpoint information is not synchronized. + * It is not safe to read or write `clients_info` + * while rmw_get_clients_info_by_service() uses it. + * - Access to C-style string arguments is read-only but it is not synchronized. + * Concurrent `service_name` reads are safe, but concurrent reads and writes are not. + * - The default allocators are thread-safe objects, but any custom `allocator` may not be. + * Check your allocator documentation for further reference. + * + * \pre Given `node` must be a valid node handle, as returned by rmw_create_node(). + * \pre Given `clients_info` must be a zero-initialized array of endpoints' information, + * as returned by rmw_get_zero_initialized_topic_endpoint_info_array(). + * + * \param[in] node Node to query the ROS graph. + * \param[in] allocator Allocator to be used when populating the `clients_info` array. + * \param[in] service_name Name of the service for client lookup, often a fully qualified + * topic name but not necessarily (see rmw_create_client()). + * \param[in] no_mangle Whether to mangle the topic name before client lookup or not. + * \param[out] clients_info Array of client information, populated on success, + * left unchanged on failure. + * If populated, it is up to the caller to finalize this array later on, + * using rmw_topic_endpoint_info_array_fini(). + * QoS Profiles in the info array will use RMW_DURATION_INFINITE for infinite durations, + * avoiding exposing any implementation-specific values. + * \return `RMW_RET_OK` if the query was successful, or + * \return `RMW_RET_INVALID_ARGUMENT` if `node` is NULL, or + * \return `RMW_RET_INVALID_ARGUMENT` if `allocator` is not valid, + * by rcutils_allocator_is_valid() definition, or + * \return `RMW_RET_INVALID_ARGUMENT` if `service_name` is NULL, or + * \return `RMW_RET_INVALID_ARGUMENT` if `clients_info` is NULL, or + * \return `RMW_RET_INVALID_ARGUMENT` if `clients_info` is not a + * zero-initialized array, or + * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if the `node` implementation + * identifier does not match this implementation, or + * \return `RMW_RET_BAD_ALLOC` if memory allocation fails, or + * \return `RMW_RET_ERROR` if an unspecified error occurs. + */ +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_get_clients_info_by_service( + const rmw_node_t * node, + rcutils_allocator_t * allocator, + const char * service_name, + bool no_mangle, + rmw_topic_endpoint_info_array_t * clients_info); + +/// Retrieve endpoint information for each known server of a given service. +/** + * This function returns an array of endpoint information for each server + * of a given service, as discovered so far by the given node. + * Endpoint information includes the server's node name and namespace, + * the associated topic type, the server's gid, and the server QoS profile. + * Names of non-existent topics are allowed, in which case an empty array will be returned. + * + * Depending on the RMW in use, discovery may be asynchronous. Therefore, creating a server + * and then calling this API may not show the newly created server immediately. + * + * \par QoS that are correctly read + * Not all QoS may be read correctly, \sa rmw_get_publishers_info_by_topic() for more details. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | Yes + * Thread-Safe | Yes + * Uses Atomics | Maybe [1] + * Lock-Free | Maybe [1] + * [1] rmw implementation defined, check the implementation documentation + * + * \par Runtime behavior + * To query the ROS graph is a synchronous operation. + * It is also non-blocking, but it is not guaranteed to be lock-free. + * Generally speaking, implementations may synchronize access to internal resources using + * locks but are not allowed to wait for events with no guaranteed time bound (barring + * the effects of starvation due to OS scheduling). + * + * \par Thread-safety + * Nodes are thread-safe objects, and so are all operations on them except for finalization. + * Therefore, it is safe to query the ROS graph using the same node concurrently. + * However, when querying topic names and types: + * - Access to the array of topic endpoint information is not synchronized. + * It is not safe to read or write `servers_info` + * while rmw_get_servers_info_by_service() uses it. + * - Access to C-style string arguments is read-only but it is not synchronized. + * Concurrent `service_name` reads are safe, but concurrent reads and writes are not. + * - The default allocators are thread-safe objects, but any custom `allocator` may not be. + * Check your allocator documentation for further reference. + * + * \pre Given `node` must be a valid node handle, as returned by rmw_create_node(). + * \pre Given `servers_info` must be a zero-initialized array of endpoints' information, + * as returned by rmw_get_zero_initialized_topic_endpoint_info_array(). + * + * \param[in] node Node to query the ROS graph. + * \param[in] allocator Allocator to be used when populating the `servers_info` array. + * \param[in] service_name Name of the service for server lookup, often a fully qualified + * topic name but not necessarily (see rmw_create_service()). + * \param[in] no_mangle Whether to mangle the topic name before server lookup or not. + * \param[out] servers_info Array of server information, populated on success, + * left unchanged on failure. + * If populated, it is up to the caller to finalize this array later on, + * using rmw_topic_endpoint_info_array_fini(). + * QoS Profiles in the info array will use RMW_DURATION_INFINITE for infinite durations, + * avoiding exposing any implementation-specific values. + * \return `RMW_RET_OK` if the query was successful, or + * \return `RMW_RET_INVALID_ARGUMENT` if `node` is NULL, or + * \return `RMW_RET_INVALID_ARGUMENT` if `allocator` is not valid, + * by rcutils_allocator_is_valid() definition, or + * \return `RMW_RET_INVALID_ARGUMENT` if `service_name` is NULL, or + * \return `RMW_RET_INVALID_ARGUMENT` if `servers_info` is NULL, or + * \return `RMW_RET_INVALID_ARGUMENT` if `servers_info` is not a + * zero-initialized array, or + * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if the `node` implementation + * identifier does not match this implementation, or + * \return `RMW_RET_BAD_ALLOC` if memory allocation fails, or + * \return `RMW_RET_ERROR` if an unspecified error occurs. + */ +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_get_servers_info_by_service( + const rmw_node_t * node, + rcutils_allocator_t * allocator, + const char * service_name, + bool no_mangle, + rmw_topic_endpoint_info_array_t * servers_info); + #ifdef __cplusplus } #endif