requests
не поддерживает asyncio
. Если вы хотите использовать истинное асинхронное выполнение, вам нужно посмотреть на библиотеки типа aiohttp или asks
Ваш набор должен быть собран до разгрузки задач, так что вы даже не выполняете дубликаты, вместо того, чтобы оптимизировать результат.
С самим requests
вы можете вернуться к run_in_executor
, который будет выполнять ваши запросы внутри ThreadPoolExecutor , поэтому на самом деле не асинхронный ввод-вывод:
import asyncio
import time
from requests import exceptions, get
def _url_exists(url):
try:
r = get(url, timeout=10)
except (exceptions.ConnectionError, exceptions.ConnectTimeout):
return False
else:
return r.status_code is 200
async def _remove_unexisting_urls(l, r):
# making a set from the list before passing it to the futures
# so we just have three tasks instead of nine
futures = [l.run_in_executor(None, _url_exists, url) for url in set(r)]
return [await f for f in futures]
rows = [ # added some dupes
'http://example.com/',
'http://example.com/',
'http://example.com/',
'http://example.org/',
'http://example.org/',
'http://example.org/',
'http://foo.org/',
'http://foo.org/',
'http://foo.org/',
]
loop = asyncio.get_event_loop()
print(time.time())
result = loop.run_until_complete(_remove_unexisting_urls(loop, rows))
print(time.time())
print(result)
выход
1537266974.403686
1537266986.6789136
[False, False, False]
Как видите, за инициализацию пула потоков взимается штраф ~ 2,3 секунды. Однако, учитывая тот факт, что каждая из этих трех задач выполняется в течение десяти секунд до истечения времени ожидания на моем компьютере (моя IDE не разрешена через прокси-сервер), общее время выполнения в двенадцать секунд выглядит вполне параллельным.