Python异步IO不显示任何错误
我试图通过使用asyncio从数千个URL获取一些数据。 以下是设计的简要概述:Python异步IO不显示任何错误,python,exception,queue,python-asyncio,aiohttp,Python,Exception,Queue,Python Asyncio,Aiohttp,我试图通过使用asyncio从数千个URL获取一些数据。 以下是设计的简要概述: 使用一个生产者用一堆URL一次性填充队列 产生一群消费者 每个使用者保持从队列异步提取URL,并发送GET请求 对结果进行一些后处理 合并所有处理的结果并返回 问题:asyncio几乎从不显示任何错误,它只是静静地挂起,没有错误。我把print语句放在各处,以便自己检测问题,但没有多大帮助 根据输入URL的数量和使用者的数量或限制,我可能会出现以下错误: 任务已销毁,但它处于挂起状态 任务异常从未被检索到:问题是您
生产者用一堆URL一次性填充队列
消费者
使用者
保持从队列
异步提取URL,并发送GET
请求asyncio
几乎从不显示任何错误,它只是静静地挂起,没有错误。我把print
语句放在各处,以便自己检测问题,但没有多大帮助
根据输入URL的数量和使用者的数量或限制,我可能会出现以下错误:
任务已销毁,但它处于挂起状态代码>
任务异常从未被检索到:问题是您的使用者只捕获两个非常特定的异常,并且在它们的情况下将任务标记为已完成。如果发生任何其他异常,例如与网络相关的异常,它将终止使用者。但是,run
没有检测到这一点,它正在等待queue.join()
,消费者(有效地)在后台运行。这就是为什么您的程序挂起-队列中的项目永远不会被考虑,队列也永远不会被完全处理
有两种方法可以解决这个问题,这取决于您希望程序在遇到意外异常时执行的操作。如果希望它继续运行,可以向使用者添加一个catch allexcept
子句,例如:
例外情况除外,如e
打印('其他错误',e)
queue.task_done()
另一种方法是将未处理的使用者异常传播到run
。这必须明确安排,但其优点是永远不允许异常以静默方式传递。(有关该主题的详细说明,请参阅。)实现此功能的一种方法是等待queue.join()
同时等待消费者;由于使用者处于无限循环中,因此只有在出现异常时,才会完成
print(“[加入队列]”)
#等待'queue.join()`完成或消费者提出请求
完成,u=wait asyncio.wait([queue.join(),*consumers],
返回(当=asyncio.FIRST\u完成时)
consumers\u raised=设置(完成)和设置(使用者)
如果消费者提出:
wait consumers_raised.pop()#传播异常
问题:如何在asyncio中检测和处理异常
异常通过wait
传播,通常像在任何其他代码中一样被检测和处理。特殊处理仅用于捕获从“后台”任务(如使用者
)泄漏的异常
如何在不中断队列的情况下重试
您可以调用wait queue.put((i,url))
在块中,除了
之外。该项目将添加到队列的后面,由消费者拾取。在这种情况下,您只需要第一个代码片段,不想费心尝试将消费者
中的异常传播到运行
谢谢您提供了如此清晰、彻底的答案。在阅读您的答案之前,我做了以下操作来解决我提到的问题:1)为了重试,我在while
循环中添加了For
循环。2) 我还在get\u video\u title
功能中添加了一个KeyError
异常3)我降低了消费者的最大数量并限制了TCP连接的最大数量4)我在get
请求中将raise\u的状态设置为False
。总之,它解决了所有问题,我能够在一分钟多一点的时间内处理1000个URL。任务管理器显示瓶颈是我的wi-fi速度