2015-10-14 3 views
3

Configuration:instance unique de apscheduler dans l'application Flask

  • l'application Flask en cours d'exécution dans le httpd d'Apache via wsgi
  • processus wsgi simple avec 25 fils de discussion: WSGIDaemonProcess myapp threads=25
  • apscheduler pour exécuter des travaux (envoyer des emails)
  • RethinkDB en tant que backend pour le magasin d'emplois

J'essaie d'empêcher l'exécution d'apscheduler en répétant le même travail plusieurs fois en empêchant le démarrage de plusieurs instances d'apscheduler. Actuellement, je suis en utilisant le code suivant pour assurer le planificateur est seulement commencé une fois:

if 'SCHEDULER' not in app.config or app.config['SCHEDULER'] is None: 
     logger.info("Configuring scheduler") 
     app.config['SCHEDULER'] = scheduler.configure() 

Cependant, quand je regarde mes journaux, je vois le planificateur étant commencé deux fois:

[07:07:56.796001 pid 24778 INFO] main.py 57:Configuring scheduler 
[07:07:56.807977 pid 24778 INFO] base.py 132:Scheduler started 
[07:07:56.812253 pid 24778 DEBUG] base.py 795:Looking for jobs to run 
[07:07:56.818019 pid 24778 DEBUG] base.py 840:Next wakeup is due at-10-14 11:30:00+00:00 (in 1323.187678 seconds) 
[07:07:57.919869 pid 24777 INFO] main.py 57:Configuring scheduler 
[07:07:57.930654 pid 24777 INFO] base.py 132:Scheduler started 
[07:07:57.935212 pid 24777 DEBUG] base.py 795:Looking for jobs to run 
[07:07:57.939795 pid 24777 DEBUG] base.py 840:Next wakeup is due at-10-14 11:30:00+00:00 (in 1322.064753 seconds) 

Comme on être vu par le pid, il y a deux processus qui sont démarrés quelque part/en quelque sorte. Comment puis-je empêcher cela? Où est cette configuration dans httpd?

Supposons que deux processus soient en cours d'exécution. Je pourrais utiliser flock pour empêcher le démarrage d'apscheduler deux fois. Toutefois, cela ne fonctionnera pas car le processus qui ne démarre PAS apscheduler ne pourra pas ajouter/supprimer des tâches car app.config['SCHEDULER'] défini pour ce processus à utiliser. Quelle est la meilleure façon de configurer/configurer une application Web Flask avec plusieurs processus qui peuvent ajouter/supprimer des tâches, tout en empêchant le planificateur d'exécuter le travail plusieurs fois?

+0

J'ai réussi à faire en sorte que httpd ne démarre qu'une fois le processus en changeant la directive mpm_event 'StartServers' à 1. Mais cela ne veut pas dire qu'il ne va pas démarrer plus de processus ... – wspeirs

Répondre

2

J'ai finalement réglé sur l'utilisation d'un verrou basé sur des fichiers pour faire en sorte que la tâche ne fonctionne pas deux fois:

def get_lock(name): 
    fd = open('/tmp/' + name, 'w') 

    try: 
     flock(fd, LOCK_EX | LOCK_NB) # open for exclusive locking 
     return fd 
    except IOError as e: 
     logger.warn('Could not get the lock for ' + str(name)) 
     fd.close() 
     return None 


def release_lock(fd): 
    sleep(2) # extend the time a bit longer in the hopes that it blocks the other proc 
    flock(fd, LOCK_UN) 
    fd.close() 

Il est un peu un hack, mais semble fonctionner ...