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


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to