简体   繁体   English

无法关闭正在运行的事件循环

[英]Cannot close a running event loop

What is the way to close the discord.py bot loop once tasks are done?任务完成后关闭 discord.py 机器人循环的方法是什么?

Added:添加:

nest_asyncio.apply()

Tried:试过:

bot.logout(), bot.close(), bot.cancel()

Code:代码:

async def helper(bot, discord_user_feed):
    nest_asyncio.apply()
    await bot.wait_until_ready()
    # await asyncio.sleep(10)
    for each_id, events_list in discord_user_feed.items():
        discord_user = await bot.fetch_user(int(each_id))
        for each_one in events_list:
            msg_sent = True
            while msg_sent:
                await discord_user.send(each_one)
                msg_sent = False
    await bot.close()
    return 'discord messages sent'


async def discord_headlines(request):
    nest_asyncio.apply()
    discord_user_feed =  await get_details()
    bot = commands.Bot(command_prefix='!')
    bot.loop.create_task(helper(bot, discord_user_feed))
    message = bot.run('my_token')
    return HttpResponse(message)

I can be able to send messages to discord users using id and discord bot.我可以使用 id 和 discord 机器人向 discord 用户发送消息。 But, even after, django view api is continuously running and getting the error.但是,即使之后,django 视图 api 仍在继续运行并出现错误。 It needs to return a response message - discord messages sent.它需要返回一个响应消息 - discord 消息发送。

Error:错误:

Exception in callback <TaskWakeupMethWrapper object at 0x000001C852D2DA38>(<Future finis...SWdZVtXT7E']}>)
handle: <Handle <TaskWakeupMethWrapper object at 0x000001C852D2DA38>(<Future finis...SWdZVtXT7E']}>)>
Traceback (most recent call last):
  File "E:\sd\envs\port\lib\asyncio\events.py", line 145, in _run
    self._callback(*self._args)
KeyError: <_WindowsSelectorEventLoop running=True closed=False debug=False>
Internal Server Error: /api/v0/discord_headlines/
Traceback (most recent call last):
  File "E:\sd\envs\port\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "E:\sd\envs\port\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\sd\envs\port\lib\site-packages\asgiref\sync.py", line 139, in __call__
    return call_result.result()
  File "E:\sd\envs\port\lib\concurrent\futures\_base.py", line 425, in result
    return self.__get_result()
  File "E:\sd\envs\port\lib\concurrent\futures\_base.py", line 384, in __get_result
    raise self._exception
  File "E:\sd\envs\port\lib\site-packages\asgiref\sync.py", line 204, in main_wrap
    result = await self.awaitable(*args, **kwargs)
  File "E:\back-end\port_api\views\discord_integration.py", line 110, in discord_headlines
    message = bot.run('my_token')
  File "E:\sd\envs\port\lib\site-packages\discord\client.py", line 719, in run
    _cleanup_loop(loop)
  File "E:\sd\envs\port\lib\site-packages\discord\client.py", line 95, in _cleanup_loop
    loop.close()
  File "E:\sd\envs\port\lib\asyncio\selector_events.py", line 107, in close
    raise RuntimeError("Cannot close a running event loop")
RuntimeError: Cannot close a running event loop
[13/Jun/2021 01:07:34] "GET /api/v0/discord_headlines/ HTTP/1.1" 500 109010

These are the versions:这些是版本:

Python 3.6.4, Django 3.1, discord.py 1.7.3, Asyncio, Anaconda-4.9.2, Windows-10

I've not used older versions so I can't attest to the accuracy of this answer for pre-2021 releases (v1.6.0+) Discord.py.我没有使用旧版本,因此我无法证明此答案对于 2021 之前版本 (v1.6.0+) Discord.py 的准确性。

When starting a discord Client or Bot via run(*args, **kwargs) there is actually no class method to stop it.通过run(*args, **kwargs)启动 discord 客户端或机器人时,实际上没有 class 方法可以停止它。

Per the Discord.py Documentations Discord.py discord.Client.run :根据 Discord.py 文档Discord.py discord.Client.run

A blocking call that abstracts away the event loop initialisation from you.从您那里抽象出事件循环初始化的阻塞调用。

If you want more control over the event loop then this function should not be used.如果您想对事件循环进行更多控制,则不应使用此 function。 Use start() coroutine or connect() + login()使用 start() 协程或 connect() + login()

And it's effectively equal to:它实际上等于:

# run(*args, **kwargs) is basically
try:
    # Start the bot on asyncio event loop with using .start() coroutine
    loop.run_until_complete(start(*args, **kwargs))
except KeyboardInterrupt:
    # Invoke close() coroutine on the same loop if interrupt
    loop.run_until_complete(close())
    # Cancel any other lingering tasks and such
finally:
    loop.close()

So the unrewarding but accurate answer with your current attempted implementation is simply... you can't.因此,您当前尝试实施的无回报但准确的答案很简单……您不能。

If you wanna drop some more info on the webserver library your using in response or via a message, I can help craft you something functional.如果您想在响应或通过消息使用的网络服务器库上提供更多信息,我可以帮助您制作一些实用的东西。

If your webserver is fully asyncio integrated, your best bet is seeing if the library has a way to add tasks to its existing event loop, or if you pass one to it.如果您的网络服务器完全集成了 asyncio,那么最好的办法是查看库是否有办法将任务添加到其现有的事件循环中,或者您是否将任务传递给它。 Sanic allows for this in its decorator startup/shutdown methods (ex. after_server_start, etc). Sanic 在其装饰器启动/关闭方法(例如 after_server_start 等)中允许这样做。 Store the reference to the bot instance somewhere and pass it around as needed.将对机器人实例的引用存储在某处并根据需要传递它。

I'll try and keep an eye on here for a response or DM and try to help get you functional and we can post updated code answer here, there's a big lack of solid answers for using discord.py in more complex cases within other applications/webservices and I just ran into a similiar issue with writing a discord.py bot that accepted webhook data and posted embeds to appropriate channels based on some filters.我将尝试关注这里的回复或 DM 并尝试帮助您发挥作用,我们可以在此处发布更新的代码答案,在其他应用程序/Web 服务中更复杂的情况下使用 discord.py 缺乏可靠的答案我刚刚遇到了一个类似的问题,即编写一个 discord.py 机器人,它接受 webhook 数据并根据一些过滤器将嵌入发布到适当的频道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spyder:无法关闭正在运行的事件循环 - Spyder: Cannot close a running event loop Python:“无法关闭正在运行的事件循环”Asyncio - Python: "Cannot close a running event loop" Asyncio RuntimeError:无法关闭正在运行的事件循环 - RuntimeError: Cannot close a running event loop 无法关闭正在运行的事件循环,当我调用 run_forever 时我无法关闭循环 - Cannot close a running event loop,when i call run_forever i can't close the loop (Python) Discord bot 代码返回“RuntimeError:无法关闭正在运行的事件循环” - (Python) Discord bot code returns "RuntimeError: Cannot close a running event loop" 如何修复运行时错误:无法关闭正在运行的事件循环 - Python Discord Bot - How to Fix Runtime Error: Cannot close a running event loop - Python Discord Bot &#39;在另一个循环正在运行时无法运行事件循环&#39;) RuntimeError websockets? - 'Cannot run the event loop while another loop is running') RuntimeError websockets? RuntimeError:无法从正在运行的事件循环中调用 asyncio.run() - RuntimeError: asyncio.run() cannot be called from a running event loop 事件循环已经在运行 - The event loop is already running 在 Google colab 上运行 Playwright 会出现错误:asyncio.run() cannot be called from a running event loop - Running Playwright on Google colab gives error : asyncio.run() cannot be called from a running event loop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM