Using loop.call_later() to ensure short-running loop iteration

How we previously did things could cause us to miss certain calls, such
as calling 'future.add_done_callback()' callbacks.
This commit is contained in:
Sybren A. Stüvel 2016-03-15 15:34:30 +01:00
parent e60853a211
commit d3e433b8b2

View File

@ -33,20 +33,21 @@ def kick_async_loop(*args):
return return
all_tasks = asyncio.Task.all_tasks() all_tasks = asyncio.Task.all_tasks()
if not all_tasks: if not len(all_tasks):
log.debug('no more scheduled tasks, stopping') log.debug('no more scheduled tasks, stopping')
stop_async_loop() stop_async_loop()
return return
if all(task.done() for task in all_tasks): if all(task.done() for task in all_tasks):
log.info('all tasks are done, fetching results and stopping.'.format(__name__)) log.info('all %i tasks are done, fetching results and stopping.', len(all_tasks))
for task in all_tasks: for task_idx, task in enumerate(all_tasks):
# noinspection PyBroadException # noinspection PyBroadException
try: try:
task.result() res = task.result()
log.debug(' task #%i: result=%r', task_idx, res)
except asyncio.CancelledError: except asyncio.CancelledError:
# No problem, we want to stop anyway. # No problem, we want to stop anyway.
pass log.debug(' task #%i: cancelled', task_idx)
except Exception: except Exception:
print('{}: resulted in exception'.format(task)) print('{}: resulted in exception'.format(task))
traceback.print_exc() traceback.print_exc()
@ -54,10 +55,12 @@ def kick_async_loop(*args):
return return
# Perform a single async loop step # Perform a single async loop step
async def do_nothing(): def stop_loop(future):
pass future.set_result('done')
loop.run_until_complete(do_nothing()) future = asyncio.Future()
loop.call_later(0.005, stop_loop, future)
loop.run_until_complete(future)
def async_loop_handler() -> callable: def async_loop_handler() -> callable: