Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: get clients, servers info #371

Open
wants to merge 2 commits into
base: rolling
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 172 additions & 0 deletions rmw/include/rmw/get_topic_endpoint_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,178 @@ 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 service type, the client's gid, and the client QoS profile.
* Names of non-existent services 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 Internal behavior
* In ROS middleware (RMW), service endpoints are internally handled as topics.
* Specifically, the client acts as a DataReader and the server as a DataWriter,
* populating the corresponding topic endpoint information. Therefore, all fields of
* `rmw_topic_endpoint_info_t` can be filled in by querying the graph cache.
*
* \par QoS that are correctly read
* Not all QoS may be read correctly, \sa rmw_get_publishers_info_by_topic() for more details.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | Yes
* Uses Atomics | Maybe [1]
* Lock-Free | Maybe [1]
* <i>[1] rmw implementation defined, check the implementation documentation</i>
*
* \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 service type, the server's gid, and the server QoS profile.
* Names of non-existent services 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 Internal behavior
* In ROS middleware (RMW), service endpoints are internally handled as topics.
* Specifically, the client acts as a DataReader and the server as a DataWriter,
* populating the corresponding topic endpoint information. Therefore, all fields of
* `rmw_topic_endpoint_info_t` can be filled in by querying the graph cache.
*
* \par QoS that are correctly read
* Not all QoS may be read correctly, \sa rmw_get_publishers_info_by_topic() for more details.
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | Yes
* Uses Atomics | Maybe [1]
* Lock-Free | Maybe [1]
* <i>[1] rmw implementation defined, check the implementation documentation</i>
*
* \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
Expand Down