I need to create a Runner class that can asynchronously runs multiple jobs and return the results one all jobs are completed. Here is the dummy code snippet which I already have
import asyncio
class Runner:
def __init__(self):
self.jobs_loop = asyncio.new_event_loop()
async def slow_process(self, *args):
... # run slow proces with args
await asyncio.sleep(5)
return "result"
def batch_run(self, count, *args):
results = self.jobs_loop.run_until_complete(asyncio.gather(
*[self.slow_process(*args) for _ in range(count)],
loop=self.jobs_loop,
return_exceptions=True
))
return results
runner = Runner()
print(runner.batch_run(10))
When the batch_run is called, it schedules count jobs and blocks until finished.
This, however, doesn't work when called from a running event loop raising
RuntimeError: Cannot run the event loop while another loop is running
How can I make batch_run work when called from existing event loop (e.g. Jupyter Console) as well as being callable from outside of the event loop.
EDIT
Ideally the function would look like this
def batch_run(self, count, *args):
loop = asyncio.get_event_loop()
jobs = asyncio.gather(...)
if not loop.is_running():
return loop.run_until_complete(jobs)
else:
future = asyncio.ensure_future(jobs, loop=loop)
# loop.wait_until_completed(future)
return future.result()
if only loop.wait_until_completed existed.