Executor cannot handle asyncio.sleep() in coroutine
See original GitHub issueBug report
Required Info:
- Operating System:
- Ubuntu 16.04 and Ubuntu 18.04
- Installation type:
- source
- Version or commit hash:
- be4bc88
- DDS implementation:
- Fast-RTPS
- Client library (if applicable):
- rclpy
Steps to reproduce issue
With a ROS 2 workspace built and sourced:
- Create
foo_service.py
with the following content:
import asyncio
from example_interfaces.srv import AddTwoInts
import rclpy
async def add_two_ints_callback(request, response):
response.sum = request.a + request.b
await asyncio.sleep(1)
print('Service request handled')
return response
def main():
rclpy.init()
node = rclpy.create_node('foo_service')
srv = node.create_service(AddTwoInts, 'add_two_ints', add_two_ints_callback)
rclpy.spin(node)
rclpy.shutdown()
if __name__ == '__main__':
main()
-
Run the service:
python3 foo_service.py
-
Run a service client:
ros2 run examples_rclpy_minimal_client client
Expected behavior
Service call succeeds without error.
Actual behavior
Service server crashes from assertion error:
AssertionError: yield from wasn't used with future
Trace:
Traceback (most recent call last):
File "service.py", line 27, in <module>
main()
File "service.py", line 22, in main
rclpy.spin(node)
File "/home/jacob/ws/actions_ws/install/rclpy/lib/python3.5/site-packages/rclpy/__init__.py", line 119, in spin
executor.spin_once()
File "/home/jacob/ws/actions_ws/install/rclpy/lib/python3.5/site-packages/rclpy/executors.py", line 573, in spin_once
raise handler.exception()
File "/home/jacob/ws/actions_ws/install/rclpy/lib/python3.5/site-packages/rclpy/task.py", line 207, in __call__
self._handler.send(None)
File "/home/jacob/ws/actions_ws/install/rclpy/lib/python3.5/site-packages/rclpy/executors.py", line 324, in handler
await call_coroutine(entity, arg)
File "/home/jacob/ws/actions_ws/install/rclpy/lib/python3.5/site-packages/rclpy/executors.py", line 282, in _execute_service
response = await await_or_execute(srv.callback, request, srv.srv_type.Response())
File "/home/jacob/ws/actions_ws/install/rclpy/lib/python3.5/site-packages/rclpy/executors.py", line 89, in await_or_execute
return await callback(*args)
File "service.py", line 11, in add_two_ints_callback
await asyncio.sleep(1)
File "/usr/lib/python3.5/asyncio/tasks.py", line 516, in sleep
return (yield from future)
File "/usr/lib/python3.5/asyncio/futures.py", line 362, in __iter__
assert self.done(), "yield from wasn't used with future"
AssertionError: yield from wasn't used with future
Additional information
The error appears related to the call to asyncio.sleep(1)
in the service server callback.
If we replace it with time.sleep(1)
, the code executes without error.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:3
- Comments:6 (4 by maintainers)
Top Results From Across the Web
Why coroutines cannot be used with run_in_executor?
You have to create and set a new event loop in the thread context in order to run coroutines: import asyncio from concurrent.futures...
Read more >Event Loop — Python 3.11.1 documentation
After calling this method, a RuntimeError will be raised if loop.run_in_executor() is called while using the default executor. Note that there is no...
Read more >How to Get the Asyncio Coroutine from a Task in Python
You can get the coroutine wrapped in a task by calling the get_coro() method on the Task object. In this tutorial, you will...
Read more >Source code for asgiref.sync - Django documentation
import asyncio.coroutines import contextvars import functools import inspect ... so that tasks can work out what their parent used. executors = Local() def ......
Read more >Coroutines (C++20) - cppreference.com
This is a non-owning handle used to resume execution of the coroutine or to destroy the coroutine frame. the coroutine state, which is...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Are there plans to support pythons async and await syntax in the future? Not beeing able to use pythons own system of coroutines and async execution is one of a the big things holding us back migrating to ROS2. With ROS1 we use the workaround provided by locusrobotics/aiorospy.
Sorry for hijacking this is issue, but it appears to be the most fitting place for my question.
There are two standard modules for executors/tasks/futures: concurrent.futures which is thread safe but does not support coroutines, and asyncio which supports coroutines but is not threadsafe. The rclpy executor supports both multiple threads and coroutines, so it has to have its own 😦