Reputation: 8915
Is a loop.close()
needed prior to returning async values in the below code?
import asyncio
async def request_url(url):
return url
def fetch_urls(x):
loop = asyncio.get_event_loop()
return loop.run_until_complete(asyncio.gather(*[request_url(url) for url in x]))
That is, should fetch_urls
be like this instead?:
def fetch_urls(x):
loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*[request_url(url) for url in x]))
loop.close()
return results
If the loop.close()
is needed, then how can fetch_urls
be called again without raising the exception: RuntimeError: Event loop is closed
?
A previous post states that it is good practice to close the loops and start new ones however it does not specify how new loops can be opened?
Upvotes: 1
Views: 146
Reputation: 30472
You can also keep the event loop alive, and close it the end of your program, using run_until_complete
more than once:
import asyncio
async def request_url(url):
return url
def fetch_urls(loop, urls):
tasks = [request_url(url) for url in urls]
return loop.run_until_complete(asyncio.gather(*tasks, loop=loop))
loop = asyncio.get_event_loop()
try:
print(fetch_urls(loop, ['a1', 'a2', 'a3']))
print(fetch_urls(loop, ['b1', 'b2', 'b3']))
print(fetch_urls(loop, ['c1', 'c2', 'c3']))
finally:
loop.close()
Upvotes: 2
Reputation: 69031
No, the async function (request
in this case) should not be closing the event loop. The command loop.run_until_complete
will close stop the event loop as soon as it runs out of things to do.
fetch_urls
should be the second version -- that is, it will get an event loop, run the event loop until there is nothing left to do, and then closes it loop.close()
.
Upvotes: 1