2011-08-24 17 views

Respuesta

7

El horario es derived from a setting, y por lo tanto parece ser inmutable en tiempo de ejecución.

Probablemente pueda lograr lo que está buscando usando Task ETAs. Esto garantiza que su tarea no se ejecutará antes de el tiempo deseado, pero no promete ejecutar la tarea en el momento designado; si los trabajadores están sobrecargados en la ETA designada, la tarea puede ejecutarse más tarde.

Si esta restricción no es un problema, se podría escribir una tarea que sería primera funcionar por sí mismo como:

@task 
def mytask(): 
    keep_running = # Boolean, should the task keep running? 
    if keep_running: 
     run_again = # calculate when to run again 
     mytask.apply_async(eta=run_again) 
    # ... do the stuff you came here to do ... 

La principal desventaja de este enfoque es que usted está confiando en la taskstore recordar las tareas en vuelo Si uno de ellos falla antes de disparar el siguiente, entonces la tarea nunca volverá a ejecutarse. Si su intermediario no persiste en el disco y muere (llevando todas las tareas en vuelo con él), entonces ninguna de esas tareas se ejecutará nuevamente.

Puede resolver estos problemas con algún tipo de registro de transacciones y una tarea periódica de "niñera" cuyo trabajo es encontrar tales tareas repetitivas que mueren prematuramente y revivirlas.

Si tuviera que implementar lo que ha descrito, creo que así es como lo abordaría.

+3

Sí, el planificador no está optimizado para las planificaciones dinámicas, pero puede implementar su propio 'Schedule' con un método' is_due' como se describe anteriormente, y tener la tarea reprogramarse es una opción que muchos usan, pero luego necesita asegúrese de que la primera tarea siempre se active, lo cual no es tan fácil. Otra opción es utilizar el DatabaseScheduler en django-apio, esto admite horarios dinámicos y también se puede usar fuera de los proyectos de Django. Además, crear tus propios programadores no es tan difícil. – asksol

+0

@asksol, la documentación para django-apio está vacía.¿Dónde puedo encontrar información sobre cómo usar databaseScheduler? – goh

+1

@amateur Bueno, la documentación es muy escasa aquí: – asksol

1

celery.task.base.PeriodicTask define is_due que determina cuándo debería ser la próxima ejecución. Puede anular esta función para contener su lógica de ejecución dinámica personalizada. Consulte la documentación aquí: http://docs.celeryproject.org/en/latest/reference/celery.task.base.html?highlight=is_due#celery.task.base.PeriodicTask.is_due

Un ejemplo:

import random 
from celery.task import PeriodicTask 

class MyTask(PeriodicTask): 

    def run(self, **kwargs): 
     logger = self.get_logger(**kwargs) 
     logger.info("Running my task") 

    def is_due(self, last_run_at): 
     # Add your logic for when to run. Mine is random 
     if random.random() < 0.5: 
      # Run now and ask again in a minute 
      return (True, 60) 
     else: 
      # Don't run now but run in 10 secs 
      return (True, 10) 
+0

¿me puede dar un ejemplo de cómo anular durante el tiempo de ejecución? Supongo que no puedo usar .delay porque no hay run() para classesTask classes – goh

+0

Usted define su propia clase de programación (apio.schedules.schedule) con un método personalizado is_due. 'CELERYBEAT_SCHEDULE = {" my name ": {" task ":" myapp.mytask ", schedule": myschedule()}} ' – asksol

0

Esto debería ayudar a algunos ... http://celery.readthedocs.org/en/latest/faq.html#can-i-change-the-interval-of-a-periodic-task-at-runtime

Una vez que haya definido una programación personalizada, asignarlo a su tarea como asksol tiene sugerido arriba

CELERYBEAT_SCHEDULE = {  
    "my_name": { 
     "task": "myapp.tasks.task", 
     "schedule": myschedule(),  
    } 
} 

También puede ser que desee modificar CELERYBEAT_MAX_LOOP_INTERVAL si desea que su horario para actualizar con mayor frecuencia que cada cinco minutos.

Cuestiones relacionadas