web-dev-qa-db-fra.com

apscheduler in Flask s'exécute deux fois

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

28
beka

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')
0
beka

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.

37
Kenny Winker

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

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.

7
tuomastik