我正在使用`discord.py在机器人上工作。该漫游器建立/删除多个通道,并连接到SQLite数据库。如果漫游器崩溃了,我希望它
这是关机协程:
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
。如何确保此代码在每种类型的出口上运行?
我使用this post来获取一些信息,我认为它与我想要的最接近。
答案 0 :(得分:1)
尝试:
try:
bot.loop.run_until_complete(bot.start(TOKEN))
finally:
bot.loop.run_until_complete(canv.shutdown())
bot.loop.close()
您想在每次关闭脚本时都删除通道并关闭数据库,不仅是崩溃时,对吗?
否则,请尝试:
try:
bot.loop.run_until_complete(bot.start(TOKEN))
except Exception:
bot.loop.run_until_complete(canv.shutdown())
raise
finally:
bot.loop.close()
更新:
根据您提供的链接:
已散发的异常信息以及异常本身可以 通过对sys.exc_info()的标准调用来检索。
让我们尝试一下:
import sys
try:
bot.loop.run_until_complete(bot.start(TOKEN))
finally:
if sys.exc_info() != (None, None, None):
bot.loop.run_until_complete(canv.shutdown())
bot.loop.close()
答案 1 :(得分:1)
您可以尝试这样的事情
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)