interactions-py / interactions.py

A highly extensible, easy to use, and feature complete bot framework for Discord
https://interactions-py.github.io/interactions.py/
MIT License
838 stars 184 forks source link

[BUG] Cannot process two interactions at once #1131

Closed Barefoot-Dev closed 2 years ago

Barefoot-Dev commented 2 years ago

Describe the bug.

If I trigger /my_first_command twice in a row, the second one fails immediately with the response 'The application did not respond', and then 10 seconds later the backed says "Uknown interaction".

Not actually sure if this is a bug or I'm just implementing incorrectly.

List the steps.

  1. Run this code
  2. Trigger /my_first_command from the Discord UI twice in a row
  3. Observe error in console
import os
import time
import asyncio
import interactions
import dotenv

# get token from env
dotenv.load_dotenv()

bot = interactions.Client(token=os.getenv("DISCORD_TOKEN"))

async def process():
    # sleep
    print("Sleeping for 10 seconds")
    time.sleep(10)

    print("Done")

@bot.command(name="my_first_command", description="This is the first command I made!")
async def my_first_command(ctx: interactions.CommandContext):
    print("Hello World!")

    # send message
    await ctx.send("Hello World!")

    # run process without blocking next interaction
    asyncio.create_task(process())

bot.start()

What you expected.

To process both Interactions without failing.

What you saw.

Instead, I received this traceback error given from my Python terminal:

interactions.api.error.LibraryException: 
  Error 10062 | Unknown Interaction.:
  Unknown interaction.
  Severity 40.

What version of the library did you use?

release

Version specification

4.3.4

Code of Conduct

Catalyst4222 commented 2 years ago

The reason why your code isn't working is because time.sleep(10`` is a blocking function. In other words, it stops the rest of the bot from running *anything*. The proper way to delay a function would be to useawait asyncio.sleep(10)`, which lets the rest of the bot run as it should

Barefoot-Dev commented 2 years ago

The reason why your code isn't working is because time.sleep(10 is a blocking function. In other words, it stops the rest of the bot from running anything. The proper way to delay a function would be to use `await asyncio.sleep(10), which lets the rest of the bot run as it should

Thanks for your reply @Catalyst4222 I'm using sleep as a minimal example, but in reality I actually have a lot of code to run, not just sleep(10). Is there a generic way to run any code in a non-blocking way?

I thought putting the blocking code inside asyncio.create_task would solve it...

Toricane commented 2 years ago

Please send your code so we can better understand what you are attempting to do.

Are you using requests or any other "blocking" code? Please use aiohttp or other asynchronous alternatives.

Does your command take longer than 3 seconds to respond? Try adding await ctx.defer() at the top of the command's code.

Barefoot-Dev commented 2 years ago

Please send your code so we can better understand what you are attempting to do.

Are you using requests or any other "blocking" code? Please use aiohttp or other asynchronous alternatives.

Does your command take longer than 3 seconds to respond? Try adding await ctx.defer() at the top of the command's code.

I am using requests, Tweepy API calls, redis calls and more. A bit much to send I think!

I am using defer, but it's the second interaction that get blocked so I can't respond even defer with it, because by the time the function runs a second time the interaction is "Unkown".

Anyway I think I've just solved it by using a thread for all the code (threading.Thread)! Thx for your help.

Toricane commented 2 years ago

Please don't use requests. Use aiohttp instead.

Barefoot-Dev commented 2 years ago

How come?

Toricane commented 2 years ago

requests is blocking so it will block other asynchronous code until it finishes, while aiohttp is built to be asynchronous. You don't need threading with aiohttp or with anything that is asynchronous because it is asynchronous and not blocking.

Barefoot-Dev commented 2 years ago

Okay, I can use aiohttp then, but I'm still inevitably going to have some blocking code, which means I can never handle multiple interactions at once?

EepyElvyra commented 2 years ago

Okay, I can use aiohttp then, but I'm still inevitably going to have some blocking code, which means I can never handle multiple interactions at once?

How come?

AstreaTSS commented 2 years ago

Guys, please.

Take this to the support server. Issues aren't a place for help, and this isn't a bug.

EepyElvyra commented 2 years ago

https://discord.gg/interactions