2016-01-20 2 views
3

Je suis en cours d'exécution d'un planificateur à l'aide pythonapscheduler intérieur web.py cadre. La fonction runserver est supposée s'exécuter tous les jours à 9 heures mais elle est incohérente. Il fonctionne la plupart du temps mais saute une fois de temps en temps.apscheduler python pas compatible

code:

import web 
from apscheduler.schedulers.blocking import BlockingScheduler #Blocking Scheduler 

#URLs 
urls = (
    '/startscheduler/','index', 
    ) 

Nightlysched = BlockingScheduler() 

@Nightlysched.scheduled_job('cron', hour=9) 
def runserver(): 
    print 2+2 #doing some calculations here 

#Main function to run the cron JOB 
if __name__ == "__main__": 
    Nightlysched.start() #stating the job 
    app = web.application(urls, globals()) 
    app.run() 

Quelle est la bonne façon de configurer le programmateur pour exécuter tous les jours à 9.a.m?

+1

Je n'arrive pas à comprendre comment ce code fonctionne. Nightlysched.start() bloquera et ne laissera pas votre application web fonctionner. Cela dit, la configuration est correcte. Veuillez activer la journalisation du débogage (définissez le niveau de journalisation de "apscheduler" sur DEBUG) pour comprendre ce qui se passe. –

+0

Une fois que le planificateur a démarré (Nightlysched.start()), il exécute l'application Web comme prévu. Pouvez-vous s'il vous plaît me dire comment définir le niveau de log de apscheduler? J'ai essayé peu de choses mais ça n'a pas marché. Merci – ashishashen

Répondre

4

APScheduler dispose d'une période de grâce pendant laquelle les travaux peuvent s'exécuter. Si, pour une raison quelconque, le planificateur est occupé et/ou si la charge de l'hôte est trop élevée, APScheduler risque de ne pas démarrer le travail à temps.

Dans ce cas, le travail sera ignoré s'il n'a pas pu être démarré pendant le délai de grâce (un message explicatif sera enregistré si vous avez initialisé la journalisation Python).

Selon la cause racine réelle:

  • Si le planificateur n'a pas réussi à planifier le travail à temps, vous pouvez utiliser misfire_grace_time=None dire APScheduler pour planifier le travail dès que possible au lieu de le jeter.
  • Par défaut, une seule instance de chaque travail peut être exécutée en même temps. Assurez-vous que l'exécution précédente est terminée. Il est possible de définir le nombre maximal d'instances pour un travail particulier que le planificateur laissera s'exécuter simultanément, en utilisant l'argument mot-clé max_instances lors de l'ajout du travail. Dans ce cas, vous devrez peut-être utiliser coalesce=False. Procédez uniquement si le travail dure plus de 24 heures (dans votre cas) et que vous acceptez que deux instances de votre travail puissent s'exécuter simultanément.
  • S'il y avait trop de travaux en cours, mais que la charge de la machine n'était pas trop élevée, cela signifie que vous avez plus de travaux que ce que vous pouvez exécuter simultanément. Vous pouvez essayer d'augmenter la taille du pool de threads utilisé par APScheduler exécuteur pour exécuter des tâches (cela dépend de votre configuration, vérifiez: http://apscheduler.readthedocs.org/en/latest/userguide.html).

En résumé, je voudrais tout d'abord essayer avec misfire_grace_period:

@Nightlysched.scheduled_job('cron', hour=9, misfire_grace_time=None) 

Comme une note, bien que, comme mentionné, je ne @ Alex pas comprendre pourquoi votre code fonctionne, parce que l'appel à Nightlysched.start() devrait bloquer et empêcher l'exécution de votre application Web. Je suppose que ce code est collé et ne représente pas vraiment ce que vous utilisez. Pour moi, il semble que vous devriez plutôt utiliser un planificateur non bloquant comme BackgroundScheduler.

+1

Merci pour l'explication détaillée jjmontes. Je vais essayer ça. Aussi, je pensais aussi que le planificateur d'arrière-plan est une meilleure option, mais n'a pas pu planifier un travail avec le planificateur d'arrière-plan tous les jours à 9 heures.Tous les exemples que j'ai pu trouver étaient configurés par intervalles, quelque chose comme scheduler.add_job (runfunction, 'interval', minutes = 15). Pouvez-vous me dire comment convertir l'intervalle en cron d'une heure par jour? – ashishashen

+0

Essayez 'scheduler.add_job (votre_fonction, trigger = 'cron', heure = 9, misfire_grace_time = None)'. L'argument trigger peut être "date", "interval" ou "cron", ou vous pouvez même implémenter votre propre classe de trigger (je n'ai jamais eu besoin de le faire;)). – jjmontes

+0

Jetez également un coup d'œil sur [le code source et le document de 'add_job'] (https://bitbucket.org/agronholm/apscheduler/src/a6545cf29831bb6d8f055aeb2fa9d5204e9bd192/apscheduler/schedulers/base.py?at=master&fileviewer=file-view -default # base.py-315), je l'ai trouvé très instructif! – jjmontes