如何使用Motor优雅关闭MongoDB Change Streams?
解决Motor 1.2.0中Change Streams关闭时的异常问题
嘿,这个问题我很熟悉——这确实是Motor 1.2.0版本里的一个已知bug,而且已经被Motor的核心开发者A. Jesse Jiryu Davis快速修复了,修复后的版本从Motor 1.2.1开始就可以用啦。
问题原因
你遇到的这一串异常,本质是Motor 1.2.0在处理Change Streams异步迭代的终止逻辑时出了问题:当你用CTRL+C终止程序后,事件循环已经开始关闭,但后台的工作线程还在尝试给一个已经处于完成状态的Future设置StopAsyncIteration异常,这直接触发了InvalidStateError,后续又因为事件循环已经关闭,导致了RuntimeError: Event loop is closed。你的最小可复现示例(MCVE)完全准确,能很好地复现这个bug场景。
解决方案
推荐方案:升级Motor版本
最省心也最彻底的方式就是把Motor升级到1.2.1或更高版本,升级后这个bug就被完全修复了,你的程序再用CTRL+C终止时就能静默关闭了。执行下面的pip命令完成升级:
pip install --upgrade motor>=1.2.1
临时权宜之计(不推荐)
如果因为某些限制暂时没法升级驱动,你可以尝试在清理步骤中给事件循环多留一点时间处理后台任务,比如修改cleanup函数:
async def cleanup(): task.cancel() with suppress(CancelledError): await task # 短暂延迟等待后台线程处理完剩余逻辑 await asyncio.sleep(0.1)
不过这个方法只是临时 workaround,可能会引入其他潜在问题,所以还是优先推荐升级驱动版本。
内容的提问来源于stack exchange,提问作者Rafa Viotti
相关产品推荐
相关产品推荐

