I need to run a certain task periodically on my Flask application. I decided to use a simple library - Schedule (https://github.com/dbader/schedule) for doing this. I am running the task scheduler on a separate thread from the main application thread. Here's the relevant code snippet.
import schedule
import time
from flask import Flask, request
from threading import Thread
app = Flask(__name__)
start_time = time.time()
def run_every_10_seconds():
print("Running periodic task!")
print "Elapsed time: " + str(time.time() - start_time)
def run_schedule():
while 1:
schedule.run_pending()
time.sleep(1)
@app.route('/', methods=['GET'])
def index():
return '<html>test</html>'
if __name__ == '__main__':
schedule.every(10).seconds.do(run_every_10_seconds)
t = Thread(target=run_schedule)
t.start()
print "Start time: " + str(start_time)
app.run(debug=True, host='0.0.0.0', port=5000)
When I run this, I'd like 'Running periodic task!' to print every 10 seconds. However, this is the output I get.
* Running on http://0.0.0.0:5000/
* Restarting with reloader
Start time: 1417002869.99
Running periodic task!
Elapsed time: 10.0128278732
Running periodic task!
Elapsed time: 10.0126948357
Running periodic task!
Elapsed time: 20.0249710083
Running periodic task!
Elapsed time: 20.0247309208
Running periodic task!
Elapsed time: 30.0371530056
Running periodic task!
Elapsed time: 30.0369319916
Clearly, for some reason, the task seems to be executing twice every 10 seconds, instead of once. However, if I run merely the task scheduler alone instead of running it alongside Flask (by simply commenting the app.run() line), it runs properly.
Start time: 1417003801.52
Running periodic task!
Elapsed time: 10.0126750469
Running periodic task!
Elapsed time: 20.0246500969
Running periodic task!
Elapsed time: 30.0366458893
What could be the reason behind this? Is there a problem with the way the tasks are queued when running multiple threads? It still doesn't explain why two tasks are being scheduled at a time when only one should be.
When you run the development server with the reloader (the default when debug=True
), the module executes twice, causing two instances of t
. You can verify this by adding print(id(t))
.
The simplest way around this is to pass use_reloader=False
to app.run
. You can see this answer for an alternative solution that allows you to use the reloader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With