J'ai un problème lorsque j'utilise Apscheduler dans mon application de flacon.
Dans mon fichier view.py, j'écris comme ceci
import time
from apscheduler.scheduler import Scheduler
def test_scheduler():
print "TEST"
print time.time()
sched = Scheduler()
sched.add_interval_job(test_scheduler, seconds=5)
sched.start()
Et puis cette méthode test_scheduler () s'exécute deux fois toutes les cinq secondes
TEST 1360844314.01 TEST 1360844314.2
Je l'ai fait, j'ai ajouté dans le paramètre add_interval_job pour démarrer après un certain moment
sched.add_interval_job(test_scheduler, seconds=5, start_date='2013-02-13 00:00')
En mode débogage, le rechargeur de Flask chargera l'application du flacon deux fois ( Comment empêcher l'initialisation de Flask deux fois en mode débogage? ). Je ne sais pas pourquoi, mais cela fait que les travaux d’apscheduler sont planifiés à deux reprises. Un print "loaded scheduler"
rapide juste avant sched.start()
le confirme.
Comme indiqué dans la réponse associée, il y a plusieurs façons de contourner ce problème. Celui que j'ai trouvé qui a le mieux fonctionné consiste simplement à désactiver le rechargeur de la manière suivante:
app.run(use_reloader=False)
Cela signifie que je dois recharger mon application manuellement au fur et à mesure que je la développe, mais c'est un petit prix à payer pour faire fonctionner Apscheduler.
Lors de l'utilisation du rechargeur, il existe les processus maître et enfant. Votre thread de planificateur s'exécute dans les deux cas. Vous devez empêcher le planificateur de s'exécuter dans le processus maître.
if not app.debug or os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
sched = Scheduler()
sched.add_interval_job(test_scheduler, seconds=5)
sched.start()
Vous pouvez démarrer le planificateur dans before_first_request()
decorator de Flask, qui " enregistre une fonction à exécuter avant la première demande à cette instance de l'application ".
import time
import atexit
from apscheduler.schedulers.background import BackgroundScheduler
def print_date_time():
print(time.strftime("%A, %d. %B %Y %I:%M:%S %p"))
@app.before_first_request
def init_scheduler():
scheduler = BackgroundScheduler()
scheduler.add_job(func=print_date_time, trigger="interval", seconds=3)
scheduler.start()
# Shut down the scheduler when exiting the app
atexit.register(lambda: scheduler.shutdown())
Notez que before_first_request()
sera toujours rappelé à la première demande après le rechargement du serveur.