2

I am building a discord bot with discordpy and I want a function to be executed every ten minutes (for a mini game) but if I use time.sleep the entire program will freeze and wait for that time, rendering my bot completely useless because of the fact that time.sleep stops the program from executing. Also discordpy works with async functions and events so trying to find a place to put a while loop is very difficult. Is there a module that I can use to execute a function every ten minutes without stopping the flow of my bot?

edit: with discordpy, you define all of your async functions so:

@client.event
async def on_message(message):
    # Code

And than at the end of the file you write: client.run() What I am saying is, I cant use an infinite while loop because of the fact that I need to reach that line, without that line the bot will be useless, So what my question is, can I "attach" a timer to my script so that every ten minutes I can execute a function?

4 Answers4

1

you use scheduling for this

import sched, time
sch = sched.scheduler(time.time, time.sleep)
def run_sch(do): 
   print("running at 10 mins")
   # do your stuff
   sch.enter(600, 1, run_sch, (do,))

sch.enter(600, 1, run_sch, (s,))
sch.run()

or you can try threading for running that specific function for every 10 mins

import threading

def hello_world():
    while True:
       print("Hello, World!")
       time.sleep(600)
t1 = threading.Thread(target=hello_world)
t1.start()
while True:
   print('in loop')
   time.sleep(1)
NAGA RAJ S
  • 409
  • 4
  • 10
  • I tried this one and I believe program execution also stops. I may just be doing it wrong. – QuBit Gaming Jun 22 '20 at 04:44
  • try second one which will not stop your execution of other task..all function in thread for which you want run in parallel – NAGA RAJ S Jun 22 '20 at 04:59
  • This one seems like itll work, but with threading does it matter if my program is force shut down. (I think its called keyboard interrupting) – QuBit Gaming Jun 22 '20 at 05:02
  • This is not a proper solution. Discord.py uses `asyncio` so the right way to do it would be awaiting for `asyncio.sleep` Please refer to my answer. – Quanta Jun 22 '20 at 14:05
0

Tell me what you think about this. If it does not work with your code then I can adjust it:

import time
starttime=time.time()
def thing():
  print('hi')
while True:
  thing()
  time.sleep(60.0 - ((time.time() - starttime) % 60.0))

It's in a while loop so I don't know how well that will work with your code but since it is a bot that runs multiple times, it might work. Of course if you want it to run only 5 times for example you can just say for i in range(5): Hope this helps!

  • There is no place to put this loop because of the fact that with discordpy, the bot executes on a loop through a function. For example you just call `client.run()` and it goes into an infinite while so, I have not found a place to put this where its effective. – QuBit Gaming Jun 22 '20 at 04:31
  • Now this does execute the function every so often but this does not allow for the execution of the bot. – QuBit Gaming Jun 22 '20 at 04:32
  • Well if your function runs on a loop, is it possible to take it out?. Do you think you can edit your question and put our code in so it is easier to help you out. Because I might be able to shove it in somewhere. –  Jun 22 '20 at 04:36
  • In discordpy you type out all of your async functions and then at the bottom you type `client.run()` which is an infinite loop, like the only way to get out of it is by killing the program. So there is no loop that I can add code to that I can see. – QuBit Gaming Jun 22 '20 at 04:45
0

Try something like this,

import schedule

def worker():
    print("Executing...")

schedule.every(10).minutes.do(worker)

while True:
    schedule.run_pending()
    time.sleep(1)

Also, there are different packages we can use to achieve this feature.

import sched
sched.scheduler(params)
Threading along with sleep.
Use of Twisted package etc..
Arun Augustine
  • 1,462
  • 9
  • 19
  • I tried to replicate this but because of the infinite while loop at the bottom of your code, program execution never reaches `client.run()` for example. In discordpy you set up all of your async functions, then at the bottom of the script you type `client.run()` and that function is the infinite loop that I need to be in, but because this uses one, I never reach it. – QuBit Gaming Jun 22 '20 at 04:43
0

Discord.py is build with python asyncio module. To sleep the current task in asyncio, you need to await on asyncio.sleep() Note that this will not block your thread or the event loop and is exactly what you should use.

import asyncio #Top of your file
...

await asyncio.sleep(10) #Doesn't blocks the rest of the program!

Creating a thread as mentioned in the answer by NAGA RAJ S is not recommended in asynchronous programs and is a waste of resource.

More about asyncio.sleep v/s time.sleep: Python 3.7 - asyncio.sleep() and time.sleep()

Quanta
  • 448
  • 2
  • 21