python - 为什么在等待异步队列时 discord.py 会阻塞/缓冲?
问题描述
消息以“波”的形式发送,即几秒钟内什么都没有,然后几乎同时发送~5 次。我遗漏了token
和channel
。
import discord, asyncio
class Bot(discord.Client):
def __init__(self, q, channel):
super().__init__()
self.q = q
self.channel_id = channel
self.bg_task = self.loop.create_task(self.send_messages())
async def on_message(self, message):
if message.author == self.user or message.channel.id != self.channel_id:
return
print(message.content)
async def send_messages(self):
await self.wait_until_ready()
channel = self.get_channel(self.channel_id)
while not self.is_closed():
msg = await self.q.get()
await channel.send(msg)
from threading import Thread
from time import sleep
q = asyncio.Queue()
def f():
while True:
q.put_nowait("hi")
sleep(2)
Thread(target=f).start()
bot = Bot(q, channel)
bot.run(token)
奇怪的是,该on_message
事件似乎没有受到影响,而且,替换msg = await self.q.get()
为
msg = "hi"
await asyncio.sleep(2)
似乎导致了预期的行为。
我不确定哪里出了问题,所以我把这个例子更具体地放在了 Discord 上。
编辑
扩展asyncio.sleep
行为,我已将循环替换send_messages
为
if 0:
msg = await self.q.get()
else:
await asyncio.sleep(0.1)
if self.q.empty():
continue
msg = await self.q.get()
await channel.send(msg)
这if
只是在原始和实验之间切换。
显然,人们希望该else
部分最多与该部分一样快if
,但是等待队列非空似乎可以完全解决问题。
我开始认为不和谐和阻塞异步队列以不可预见的方式交互
另一方面,似乎channel.send
是阻塞线,所以也许它也与速率有关。
解决方案
这是因为通过 Discord 的 API 发送消息的速率限制为 5 / 5 秒。
这就是为什么您会看到一次发送 5 条消息,然后由于下一条消息的速率受限而延迟。
推荐阅读
- java - Mybatis 同时使用 WHERE IF DESC 和 LIMIT 时,IDEA 显示 Unable to resolve table 'LIMIT'
- java - 单个字符串中的多个字符串替换生成所有可能的组合
- mysql - 在 sql 单元格中传递多个前值
- asynchronous - 未来
, async, await, then, Flutter/Dart 中的 catchError - jquery - 猫头鹰轮播项目不会滚动
- javascript - Netsuite SuiteScript 礼品卡问题
- azure - Azure Function App:在门户中为新功能应用加载 V3 时出错?
- apache - 为重写路径禁用 htaccess 身份验证
- python - re 模块中的 Findall() 没有给我与搜索相同的结果
- sql - 根据不同的列选择 Top 1