python - 有没有办法使用 atexit 运行 asyncio 协程?
问题描述
我正在使用`discord.py 开发一个机器人。该机器人创建/删除多个通道,并连接到 SQLite 数据库。如果机器人崩溃,我希望它崩溃
- 销毁它创建的所有临时语音通道。
- 断开与 SQL 数据库的连接。
这是关闭协程:
async def shutdown(self):
print("Shutting down Canvas...")
for ch in self.active_channels:
await client.delete_channel(ch)
self.db.close()
我尝试过的事情:
# Canv is the interface between the bot and the data we're collecting
atexit.register(canv.shutdown)
bot.run(TOKEN)
try:
bot.loop.run_until_complete(bot.start(TOKEN))
except KeyboardInterrupt or InterruptedError:
bot.loop.run_until_complete(canv.shutdown())
finally:
bot.loop.close()
from async_generator import asynccontextmanager
@asynccontextmanager
async def cleanup_context_manager():
try:
yield
finally:
await canv.shutdown()
with cleanup_context_manager():
bot.run(TOKEN)
这些都没有运行canv.shutdown()
,这是一个asyncio.coroutine
. 如何确保此代码在每种类型的出口上运行?
我用这篇文章获取了一些信息,我认为它最接近我想要的。
解决方案
你可以试试这样的
import asyncio
import atexit
@atexit.register
def shutdown(self):
print("Shutting down Canvas...")
loop = asyncio.get_event_loop()
loop.run_until_complete(await_delete_channels())
self.db.close()
async def await_delete_channels(self):
# # Works but it is better to do it asynchronously
# for ch in self.active_channels:
# await client.delete_channel(ch)
#
# Doing delete_channels() asynchronously
delete_channels = [client.delete_channel(ch) for ch in self.active_channels]
await asyncio.wait(delete_channels, return_when=asyncio.ALL_COMPLETED)
推荐阅读
- python - 如何在 WSL Ubuntu 中激活 Windows conda 环境?
- python - 如何消除不必要的空白?
- assembly - 您可以更改引导加载程序中的字符编码还是需要第二个?
- google-apps-script - 从 GDrive Addon 中的选择中注入文件夹 ID 并抑制 cardflip
- node.js - 如何在不保存文件的情况下从节点/快递发送数据到前面的预览pdf?
- spring - 如何获取具有相同电话号码的对象列表
- git - Git 提交和 Git 推送分支是特定的吗
- sql-server - 从 docker 容器连接到 SQL Server LocalDB
- reactjs - 为什么 chrome 开发工具控制台在一个网站上显示 Post 500 错误的链接,而在另一个网站上却没有?
- r - combn(levels(Factor), 2) 中的错误:n < m 使用 EcoUtils adonis.pair 函数