1

I have a django project in combination with celery and my need is to be able to schedule tasks dynamically, at some point in the future, with recurrence or not. I need the ability to delete/edit already scheduled tasks

So to achieve this at the beginning I started using django-celery with DatabaseScheduler to store some PeriodicTasks (with expiration) to the database as it is described more or less here

In this way if I close my app and start it again my schedules are still there

My problem though still remains since I cannot utilize the eta and schedule a task at some point in the future. Is it possible somehow to dynamically schedule a task with eta?

A second question of mine is whether I can schedule a once off task, like schedule it to run e.g. at 2015-05-15 15:50:00 (that is why I'm trying to use eta)

Finally, I will be scheduling some thousants of notifications, is celery beat capable to handle this number of scheduled tasks? some of them once-off while others being periodic? Or do I have to go with a more advanced solution such as APScheduler

Thank you

Community
  • 1
  • 1
tbo
  • 9,398
  • 8
  • 40
  • 51
  • You don't want to use countdown right? Could you tell use more about the tasks you want to perform. I think I don't get the right idea about what you plan to do – Maximilian Kindshofer Apr 01 '15 at 13:24
  • Hi Maximilian and thanks for your interest, I have edited my question a bit to make it more clear – tbo Apr 01 '15 at 14:46

1 Answers1

0

I've faced the same problem yesterday. My ugly temporary solution is:

# tasks.py    
from djcelery.models import PeriodicTask, IntervalSchedule
from datetime import timedelta, datetime
from django.utils.timezone import now

...

@app.task
def schedule_periodic_task(task='app.tasks.task', task_args=[], task_kwargs={},
                           interval=(1, 'minute'), expires=now()+timedelta(days=365*100)):
    PeriodicTask.objects.filter(name=task+str(task_args)+str(task_kwargs)).delete()
    task = PeriodicTask.objects.create(
        name=task+str(task_args)+str(task_kwargs), task=task,
        args=str(task_args),
        kwargs=str(task_kwargs),
        interval=IntervalSchedule.objects.get_or_create(
            every=interval[0],
            period=interval[1])[0],
        expires=expires,
    )
    task.save()

So, if you want to schedule periodic task with eta, you shoud

# anywhere.py    
schedule_periodic_task.apply_async(
    kwargs={'task': 'grabber.tasks.grab_events',
            'task_args': [instance.xbet_id], 'task_kwargs': {},
            'interval': (10, 'seconds'),
            'expires': instance.start + timedelta(hours=3)},
    eta=instance.start,
)

schedule task with eta, which creates periodic task. Ugly:

  1. deal with raw.task.name
  2. strange period (n, 'interval')

Please, let me know, if you designed some pretty solution.