asyncio - run coroutine in the background

Frank Millman frank at chagford.com
Mon Feb 15 01:35:16 EST 2016


Hi all

Using asyncio, there are times when I want to execute a coroutine which is 
time-consuming. I do not need the result immediately, and I do not want to 
block the current task, so I want to run it in the background.

run_in_executor() can run an arbitrary function in the background, but a 
coroutine needs an event loop. After some experimenting I came up with 
this -

class BackgroundTask:
    async def run(self, coro, args, callback=None):
        loop = asyncio.get_event_loop()
        loop.run_in_executor(None, self.task_runner, coro, args, callback)

    def task_runner(self, coro, args, callback):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        fut = asyncio.ensure_future(coro(*args))
        if callback is not None:
            fut.add_done_callback(callback)

        loop.run_until_complete(fut)
        loop.close()

Usage -

    bg_task = BackgroundTask()
    args = (arg1, arg2 ...)
    callback = my_callback_function
    await bg_task.run(coro, args, callback)

Although it 'awaits' bk_task.run(), it returns immediately, as it is simply 
waiting for run_in_executor() to be launched.

Hope this is of some interest.

Frank Millman





More information about the Python-list mailing list