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