TheLegendWeeb
TheLegendWeeb

Reputation: 73

How can I make a timer for a command without blocking the program

I am trying to add a command that when entered, after some seconds sends a message back. I arrived at a solution, but it blocks the program, so other users can't use the bot until the timer is finished.

I also tried to use background tasks, but it kept telling me that it doesn't have a 'start' method.

EDIT: The code is just a example, I wanted to be able to execute other code while its waiting (where pass would go)

This is my code for the cog:

import discord
from discord.ext import tasks, commands
import time


class archive(commands.Cog):
    def __init__(self,bot):
        self.bot=bot

    @commands.Cog.listener()
    async def on_ready(self):
        print("Loaded 'Archive' module")

    @commands.command()
    async def test(self,ctx):
        target_time=time.time()+5
        while time.time()<target_time:
            pass
        await ctx.send("5 seconds have passed")


def setup(bot):
    bot.add_cog(archive(bot))

Upvotes: 2

Views: 1468

Answers (1)

Inspi
Inspi

Reputation: 599

If you just want to wait you need to use asyncio.sleep so other async code can be executed while waiting:

import asyncio


@commands.command()
async def test(self, ctx):
    await asyncio.sleep(5)
    await ctx.send("5 seconds have passed")

(Also you need to use await for ctx.send since it's a coroutine)

EDIT: if you want your test command to run some code but timeout after X seconds then you need to use asyncio.wait_for:

from random import random
import asyncio


async def my_task():
    for i in range(10):
        print(f"randomly long task: {i}/10")
        await asyncio.sleep(random())

@commands.command()
async def test(self, ctx):
    try:
        await asyncio.wait_for(my_task(), timeout=5)
        await ctx.send("Task successful")
    except asyncio.TimeoutError:
        await ctx.send("Task timed out (5 seconds)")

Upvotes: 2

Related Questions