From 2413b1053634891ed6c7df4ec1c38cc243990355 Mon Sep 17 00:00:00 2001 From: Jonas Vautherin Date: Mon, 11 May 2020 14:20:18 +0200 Subject: [PATCH] Fix tasks termination for Python 3.8 See discussion here: https://bugs.python.org/issue38559 --- examples/camera.py | 19 +++++++++++++------ examples/mission.py | 15 ++++++++++++--- examples/telemetry_takeoff_and_land.py | 16 ++++++++++++---- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/examples/camera.py b/examples/camera.py index 91c06990..22c4d3c6 100755 --- a/examples/camera.py +++ b/examples/camera.py @@ -16,8 +16,9 @@ async def run(): print(f"Drone discovered with UUID: {state.uuid}") break - asyncio.ensure_future(print_camera_mode(drone)) - asyncio.ensure_future(print_status(drone)) + print_mode_task = asyncio.ensure_future(print_mode(drone)) + print_status_task = asyncio.ensure_future(print_status(drone)) + running_tasks = [print_mode_task, print_status_task] print("Setting mode to 'PHOTO'") try: @@ -33,14 +34,20 @@ async def run(): except CameraError as error: print(f"Couldn't take photo: {error._result.result}") - # Shut down the running coroutines (here 'print_camera_mode()' and + # Shut down the running coroutines (here 'print_mode()' and # 'print_status()') + for task in running_tasks: + task.cancel() + try: + await task + except asyncio.CancelledError: + pass await asyncio.get_event_loop().shutdown_asyncgens() -async def print_camera_mode(drone): - async for camera_mode in drone.camera.mode(): - print(f"Camera mode: {camera_mode}") +async def print_mode(drone): + async for mode in drone.camera.mode(): + print(f"Camera mode: {mode}") async def print_status(drone): diff --git a/examples/mission.py b/examples/mission.py index 5d6403d3..29f6e05a 100755 --- a/examples/mission.py +++ b/examples/mission.py @@ -16,8 +16,10 @@ async def run(): print(f"Drone discovered with UUID: {state.uuid}") break - asyncio.ensure_future(print_mission_progress(drone)) - termination_task = asyncio.ensure_future(observe_is_in_air(drone)) + print_mission_progress_task = asyncio.ensure_future(print_mission_progress(drone)) + + running_tasks = [print_mission_progress_task] + termination_task = asyncio.ensure_future(observe_is_in_air(drone, running_tasks)) mission_items = [] mission_items.append(MissionItem(47.398039859999997, @@ -74,7 +76,7 @@ async def print_mission_progress(drone): f"{mission_progress.total}") -async def observe_is_in_air(drone): +async def observe_is_in_air(drone, running_tasks): """ Monitors whether the drone is flying or not and returns after landing """ @@ -85,7 +87,14 @@ async def observe_is_in_air(drone): was_in_air = is_in_air if was_in_air and not is_in_air: + for task in running_tasks: + task.cancel() + try: + await task + except asyncio.CancelledError: + pass await asyncio.get_event_loop().shutdown_asyncgens() + return diff --git a/examples/telemetry_takeoff_and_land.py b/examples/telemetry_takeoff_and_land.py index d638e3d0..cbc7be21 100755 --- a/examples/telemetry_takeoff_and_land.py +++ b/examples/telemetry_takeoff_and_land.py @@ -35,9 +35,11 @@ async def run(): break # Start parallel tasks - asyncio.ensure_future(print_altitude(drone)) - asyncio.ensure_future(print_flight_mode(drone)) - termination_task = asyncio.ensure_future(observe_is_in_air(drone)) + print_altitude_task = asyncio.ensure_future(print_altitude(drone)) + print_flight_mode_task = asyncio.ensure_future(print_flight_mode(drone)) + + running_tasks = [print_altitude_task, print_flight_mode_task] + termination_task = asyncio.ensure_future(observe_is_in_air(drone, running_tasks)) # Execute the maneuvers print("-- Arming") @@ -78,7 +80,7 @@ async def print_flight_mode(drone): print(f"Flight mode: {flight_mode}") -async def observe_is_in_air(drone): +async def observe_is_in_air(drone, running_tasks): """ Monitors whether the drone is flying or not and returns after landing """ @@ -89,6 +91,12 @@ async def observe_is_in_air(drone): was_in_air = is_in_air if was_in_air and not is_in_air: + for task in running_tasks: + task.cancel() + try: + await task + except asyncio.CancelledError: + pass await asyncio.get_event_loop().shutdown_asyncgens() return