Discord.py 机器人响应时间过长

Discord.py Bot Takes too Long to Respond

目标:

我正在开发一个 discord 机器人,它每 5 秒左右扫描一次 url,检查该网页上的 指定 更改,并发送一条消息如果发生这种变化,请在不和谐频道中。我通过使用 on_message 中的 if 语句将 url 发送到机器人来完成此操作。然后将 url 传递给 tasks.loop() 函数,在另一个函数中对其进行扫描和处理以进行更改。

问题:

我希望能够在 discord 频道中发送一条消息,该消息可以快速结束 tasks.loop() 中发生的进程,这样我就可以将它传递给另一个 url 进行扫描使用 on_message 函数。在目前的形式下,它可以工作——只是 非常 缓慢。从发送取消触发器开始,大约需要 3 分钟才能发送流程已取消的验证消息。我需要让这 5 秒或更短。对于它的价值,机器人使用 replit and uptime robot 保持 运行,但我确信较长的响应时间与 uptime 机器人唤醒 repl 的频率无关。

代码:

我的代码要复杂得多,并且充斥着晦涩难懂的命名变量,所以这里有一个更简单的代码片段,具有相同的通用结构。

client = discord.Client()
channel = client.get_channel(CHANNEL_ID)

@tasks.loop()
async def myloop(website, dataframe):
    
    channel = client.get_channel(CHANNEL_ID)
    
    try:
        # iteratively scrape data from a website for
        # a predefined change in the dataframe
        if change = True:
            await channel.send(notification)
            
    except:
        pass


@client.event
async def on_message(message):
    
    channel = client.get_channel(CHANNEL_ID)
    msg = message.content
    
    if msg.startswith('track'):
        
        website = msg[6:]
        await channel.send('Now tracking '+str(website))
        myloop(website,df)

    if msg.starswith('stop'):
        
        myloop.cancel()
        await channel.send('Done tracking, awaiting orders.')

        

尝试的解决方案:

我尝试过使用某些形式的线程,我对它很陌生,但我还没有找到让它工作得更快的方法。任何建议或解决方案将不胜感激!一段时间以来,我一直在网上寻求帮助。

看起来您可以使用 client.loop.create_task 来创建异步任务对象,并使用它们的 cancel 方法在正确的时间立即取消这些异步任务,例如

import asyncio
from replit import db


_task = None


async def myloop():
    website = db['website']
    dataframe = db['dataframe']
    channel = client.get_channel(CHANNEL_ID)

    while not client.is_closed():
        await asyncio.sleep(5)
        try:
            # iteratively scrape data from a website for
            # a predefined change in the dataframe
            if change:
                await channel.send(notification)
        except:
            pass


@client.event
async def on_message(message):
    global _task  # This gives the function access to the variable that was already created above.
    msg = message.content
    
    if msg.startswith('track'):
        website = msg[6:]
        await message.channel.send('Now tracking '+str(website))
        db['website'] = website
        db['dataframe'] = df
        if _task is not None:
            _task.cancel()
        _task = client.loop.create_task(myloop())

    if msg.startswith('stop'):
        if _task is not None:
            _task.cancel()
            _task = None
            await message.channel.send('Done tracking, awaiting orders.')

参数create_task采用的是一个不带参数的协程,因此网站URL和数据框需要以不同的方式访问函数(我不确定你是哪种方式会更喜欢或最好;使用 replit 的数据库只是一个例子)。

通过这种方法,您应该能够再次使用 track 来更改正在监视的网站,而无需在两者之间使用 stop

文档中有更多详细信息: