无法在 quart 生命周期中访问 discord bot 实例
Unable to access discord bot instance in quart lifecycle
我对事件循环感到困惑,这可能是一个常见问题,因为似乎人们正在将 discord.py 与 quart 一起使用。我正在尝试整合 discord.py、夸脱和芹菜。
我有一个 manage.py 看起来像这样。它公开了 app 和 celery,分别由 hypercorn 和 celery 使用。我正在尝试让 celery
使用 discord.py 实例
# ./manage.py
from backend import create_app, create_celery
from backend.config import Config
app = create_app()
# celery tasks
celery = create_celery(app)
if __name__ == '__main__':
app.run(port = 8000)
在 ./backend/init.py 中我定义了 create_celery() 和 create_app()
# ./backend/__init__.py
import os
import asyncio
from quart import Quart
from backend.config import Config
from discord.ext import commands
from cogs import MainCog
from celery import Celery
import backend.celeryconfig as celeryconfig
def create_app(script_info=None):
app = Quart(__name__)
app.config.from_object(Config)
# inject discord bot
@app.before_serving
async def before_serving(app):
loop = asyncio.get_event_loop()
app.discord_bot = commands.Bot(
command_prefix=">" )
# add cogs here
app.discord_bot.add_cog(MainCog(app.discord_bot))
# connect bot
await app.discord_bot.login(Config.DISCORD_BOT_TOKEN)
loop.create_task(app.discord_bot.connect())
return app
def create_celery(app):
celery = Celery(
app.import_name,
backend=app.config['CELERY_RESULT_BACKEND'],
broker=app.config['CELERY_BROKER_URL']
)
celery.conf.update(app.config)
celery.config_from_object(celeryconfig)
class ContextTask(celery.Task):
def __call__(self, *args, **kwargs):
async def helper(self, *args, **kwargs):
async with app.app_context():
return await self.run(*args, **kwargs)
loop = asyncio.get_running_loop() # <-- I'm confused about this
coroutine = helper(self, *args, **kwargs)
loop.run_until_complete(coroutine)
celery.Task = ContextTask
return celery
当我调用 asyncio.get_running_loop() 时,我没有得到 运行 事件循环
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/celery/app/trace.py", line 450, in trace_task
R = retval = fun(*args, **kwargs)
File "/app/backend/__init__.py", line 59, in __call__
loop = asyncio.get_running_loop()
RuntimeError: no running event loop
如何从 celery 的上下文中访问 app.discord_bot?
不完全是错误的答案,但另一种方法是使用 discord-ext-ipc
而不是在 discord.py 和 quart 之间进行 ipc 通信。在这种方法中,增加 ASGI 服务器中的工作人员数量会增加 discord 机器人实例的数量,从而导致在 discord 服务器上重复响应。
我对事件循环感到困惑,这可能是一个常见问题,因为似乎人们正在将 discord.py 与 quart 一起使用。我正在尝试整合 discord.py、夸脱和芹菜。
我有一个 manage.py 看起来像这样。它公开了 app 和 celery,分别由 hypercorn 和 celery 使用。我正在尝试让 celery
使用 discord.py 实例# ./manage.py
from backend import create_app, create_celery
from backend.config import Config
app = create_app()
# celery tasks
celery = create_celery(app)
if __name__ == '__main__':
app.run(port = 8000)
在 ./backend/init.py 中我定义了 create_celery() 和 create_app()
# ./backend/__init__.py
import os
import asyncio
from quart import Quart
from backend.config import Config
from discord.ext import commands
from cogs import MainCog
from celery import Celery
import backend.celeryconfig as celeryconfig
def create_app(script_info=None):
app = Quart(__name__)
app.config.from_object(Config)
# inject discord bot
@app.before_serving
async def before_serving(app):
loop = asyncio.get_event_loop()
app.discord_bot = commands.Bot(
command_prefix=">" )
# add cogs here
app.discord_bot.add_cog(MainCog(app.discord_bot))
# connect bot
await app.discord_bot.login(Config.DISCORD_BOT_TOKEN)
loop.create_task(app.discord_bot.connect())
return app
def create_celery(app):
celery = Celery(
app.import_name,
backend=app.config['CELERY_RESULT_BACKEND'],
broker=app.config['CELERY_BROKER_URL']
)
celery.conf.update(app.config)
celery.config_from_object(celeryconfig)
class ContextTask(celery.Task):
def __call__(self, *args, **kwargs):
async def helper(self, *args, **kwargs):
async with app.app_context():
return await self.run(*args, **kwargs)
loop = asyncio.get_running_loop() # <-- I'm confused about this
coroutine = helper(self, *args, **kwargs)
loop.run_until_complete(coroutine)
celery.Task = ContextTask
return celery
当我调用 asyncio.get_running_loop() 时,我没有得到 运行 事件循环
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/celery/app/trace.py", line 450, in trace_task
R = retval = fun(*args, **kwargs)
File "/app/backend/__init__.py", line 59, in __call__
loop = asyncio.get_running_loop()
RuntimeError: no running event loop
如何从 celery 的上下文中访问 app.discord_bot?
不完全是错误的答案,但另一种方法是使用 discord-ext-ipc
而不是在 discord.py 和 quart 之间进行 ipc 通信。在这种方法中,增加 ASGI 服务器中的工作人员数量会增加 discord 机器人实例的数量,从而导致在 discord 服务器上重复响应。