Skip to content

Executor cannot handle asyncio.sleep() in coroutine #279

@jacobperron

Description

@jacobperron

Bug report

Required Info:

  • Operating System:
    • Ubuntu 16.04 and Ubuntu 18.04
  • Installation type:
    • source
  • Version or commit hash:
  • DDS implementation:
    • Fast-RTPS
  • Client library (if applicable):
    • rclpy

Steps to reproduce issue

With a ROS 2 workspace built and sourced:

  1. 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()
  1. Run the service:

     python3 foo_service.py
    
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions