Reputation: 51
I have a simple script that create async tasks for loading different pages. The first request fails with TimeoutError, and it causes next queries to fail too. But the second one has much longer timeout and should pass.
Is it possible let other queries don't fail?
import aiohttp
import asyncio
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)s %(levelname)s %(message)s')
async def main():
asyncio.ensure_future(
load_page('https://www.netflix.com:5000'))
asyncio.ensure_future(
load_page('http://bash.im/', 10))
asyncio.ensure_future(
load_page('https://myshows.me/'))
asyncio.ensure_future(
load_page('http://www.lostfilm.tv/'))
async def load_page(url, timeout=3):
try:
async with session.get(url, timeout=timeout) as response:
text = await response.text()
print(len(text))
except Exception:
logging.warning(type(e))
if __name__ == '__main__':
loop = asyncio.get_event_loop()
conn = aiohttp.TCPConnector(limit=1)
session = aiohttp.ClientSession(connector=conn, loop=loop)
asyncio.ensure_future(main())
loop.run_forever()
Log:
2017-06-26 13:57:37,869 asyncio DEBUG Using selector: EpollSelector
2017-06-26 13:57:41,780 root WARNING <class 'concurrent.futures._base.TimeoutError'>
2017-06-26 13:57:41,780 root WARNING <class 'concurrent.futures._base.TimeoutError'>
2017-06-26 13:57:41,780 root WARNING <class 'concurrent.futures._base.TimeoutError'>
2017-06-26 13:57:48,780 root WARNING <class 'concurrent.futures._base.TimeoutError'>
Upvotes: 4
Views: 1102
Reputation: 9856
Yes, It's possible. I rewrite your code and use some of this concept to fill your's requests:
I used itertools.starmap
in order to pass multiple arguments and create a list of each arguments which passed to the load_page
function.
I used asyncio.gather
in order to wrap the tasks together, and used changed the return_exceptions flag to true to ensure that the exceptions won't raised.
Changed the async
before the def main
. It returns the gathered tasks right now.
I closed the loop in the end.
The code:
import aiohttp
import asyncio
import logging
import itertools
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)s %(levelname)s %(message)s')
def main(session):
args = [
('https://www.netflix.com:5000', session,),
('http://bash.im/', session, 10),
('https://myshows.me/', session,),
('http://www.lostfilm.tv/', session,),
]
tasks = itertools.starmap(load_page, args)
futures = map(asyncio.ensure_future, tasks)
return asyncio.gather(*futures, return_exceptions=True)
async def load_page(url, session, timeout=3):
try:
async with session.get(url, timeout=timeout) as response:
text = await response.text()
print(len(text))
except Exception:
logging.warning(type(e))
if __name__ == '__main__':
loop = asyncio.get_event_loop()
conn = aiohttp.TCPConnector(limit=1)
session = aiohttp.ClientSession(connector=conn, loop=loop)
loop.run_until_complete(main(session))
loop.close()
For more reading about: asyncio.gather.
For more reading about: itertools.starmap.
Enjoy!
Upvotes: 1