使用asyncio.wait(coro_obj,return_when = FIRST_COMPLETED)时是否有机会处理异常?
我正试图从几个外部资源获取我的IP。但是,当其中一个提供的网址被破坏时,我无法处理该异常。当任何请求返回ip时,循环执行应该停止。
bcomp file1 file2
我可以在return_when = ALL_COMPLETED但不是FIRST_COMPLETED时捕获异常
我收到了以下错误:
import asyncio
import aiohttp
from concurrent.futures import FIRST_COMPLETED
SERVICES = [
('ip-api1', 'http://ip-api.com/json', 'query'),
('broken_api', 'http://broken', 'query'),
]
async def get_ip(session, service, url, ip_attr):
print('fetching ip from: {}'.format(service))
async with session.get(url) as resp:
json_resp = await resp.json()
ip = json_resp[ip_attr]
return service, ip
async def get_ip_from_services():
async with aiohttp.ClientSession() as session:
coro_obj = [get_ip(session, service[0], service[1], service[2])
for service in SERVICES]
try:
done, pending = await asyncio.wait(coro_obj, return_when=FIRST_COMPLETED)
result = done.pop().result()
print(result)
for future in pending:
future.cancel()
except:
print('catched')
loop = asyncio.get_event_loop()
loop.run_until_complete(get_ip_from_services())
loop.close()
或警告
fetching ip from: ip-api1
fetching ip from: broken_api
catched
exception calling callback for <Future at 0x103839240 state=finished returned list>
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/_base.py", line 297, in _invoke_callbacks
callback(self)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/futures.py", line 419, in _call_set_state
dest_loop.call_soon_threadsafe(_set_state, destination, source)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 620, in call_soon_threadsafe
self._check_closed()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 357, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
Task was destroyed but it is pending!
task: <Task pending coro=<ThreadedResolver.resolve() running at /Volumes/external/venv/lib/python3.6/site-packages/aiohttp/resolver.py:31> wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel() at /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/futures.py:408, <TaskWakeupMethWrapper object at 0x103807948>()]> cb=[shield.<locals>._done_callback() at /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/tasks.py:679]>
Task was destroyed but it is pending!
task: <Task pending coro=<get_ip() done, defined at ./run_7.py:15> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x1038073d8>()]>>
答案 0 :(得分:2)
我认为这是aiohttp中的一个错误,我发布了它there。
你收到的异常似乎并不重要,所以你可以保留它,直到它在aiohttp中修复。如果您不想立即查看请求,请不要取消请求。
您的代码几乎没有相关说明:
1)不要将Test Failed: expected [('Rudolph, Wilma', '1-410-5313-584','wilma@olympians.com'), ('Summitt, Pat', '1-865-355-4320', 'pat@greatcoaches.com')] but got [('Rudolph, Wilma', '1-410-5313-584', 'wilma@olympians.com')]
Pass
与concurrent.futures
一起使用:这些是不同的模块。使用asyncio
。
2)你不仅要取消任务,还要等待它被取消(它会提升asyncio.FIRST_COMPLETED
)。可以使用以下代码完成:
CancelledError
详细了解任务/取消here。