When somebody tries to call a service in a callback, for example:
# create a client that will call a service
client = node.create_client(SomeService, 'some_service')
# create subscription with a callback that calls a service
def callback(msg):
req = Request()
result = client.call(req) # deadlocks here
subscription = node.create_subscription(String, 'cause_deadlock', callback, 10)
a deadlock immediately occurs. This is a very easy mistake to make. The only thing “preventing” this mistake from being made is a docstring in rclpy
.
More should be done to prevent this, such as:
-
Tutorials: The tutorials and examples only show the use of
call_async()
. If the synchronouscall()
API is to exist as a feature on the same tier ascall_async()
, there should be official tutorials and examples to warn against incorrect usage. Right now, the only resources online that are somewhat relevant to this topic are maybe some questions on ROS Answers (such as here and here). And/or -
Deprecate/Remove:
rclcpp
does not have an equivalent API for synchronously sending a request to a service.rclpy
shouldn’t need one either. It feels likecall()
was introduced to workaround the inconvenience of howrclpy.task.Future
doesn’t have a blockingget()
similar to C++'sstd::future
.
Thoughts on this?