Executing a function after a certain period of time

Viewed 779

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 Answers

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)

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!

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..

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()

Related