Python Forum

Full Version: How to add coroutine to a running event loop?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Python 3.5

Initially, I launched several coroutine in ordered stages (which in the coroutine contain their tasks):
async def _create_workers(self):
    scheme = get_scheme()
    for stage in scheme.get_next_stage():
        await asyncio.gather(*stage)

loop = asyncio.get_event_loop()
loop.run_until_complete(self._create_workers())
But in the process of work, it became known that one of the coroutine doesn't have time to done with its tasks, and I want to add copies of it. I analyze the load from one of the coroutine ('main'- coroutine), which adds data for processing. But if I create new task I have to wait for the new coroutine to complete:
new_task = asyncio.ensure_future(slow_coro())
await new_task
But I don’t want to stop the execution flow 'main'- coroutine for waiting! I just want to add it to the current stage and so that the processing stage will finish only when the new coroutine is also completed.

How I can do it?
Don't use await until you want to stop adding things to the event loop. Whatever you want to be running together, add to the event loop, and then after they're all added is when you await the various tasks. Here's an example:

import asyncio

async def worker():
    print("Starting work")
    await asyncio.sleep(5)
    print("Work complete")

async def other_worker():
    print("Starting other worker")
    await asyncio.sleep(2)
    print("Other worker complete")

async def third_worker():
    print("Starting third worker")
    await asyncio.sleep(1)
    print("Third worker complete")

async def main():
    print("Starting workers")
    tasks = []
    tasks.append(asyncio.ensure_future(worker()))
    tasks.append(asyncio.ensure_future(other_worker()))

    print("First two workers added to the event loop.")
    for task in tasks:
        await task

    print("Adding third worker to the event loop.")
    await third_worker()
    # in this case, this is the same thing
    await asyncio.ensure_future(third_worker())

asyncio.run(main())
Output:
Starting workers First two workers added to the event loop. Starting work Starting other worker Other worker complete Work complete Adding third worker to the event loop. Starting third worker Third worker complete Starting third worker Third worker complete