Question

I'm trying to create some Celery Periodic Tasks, and a few of them need to have the ability to change the run_every time at runtime. The Celery documentation says I should be able to do this by turning the run_every attribute into a property (http://packages.python.org/celery/faq.html#can-i-change-the-interval-of-a-periodic-task-at-runtime).

Here is what I'm doing:

class ParseSomeStuffTask(PeriodicTask):

    def run(self, **kwargs):
        # Do stuff

    @property
    def run_every(self):
        if datetime.now().weekday() in [1, 2, 3]:
            return timedelta(minutes=15)
        else:
            return timedelta(seconds=40)

Unfortunately, when I turn on celerybeat, I get the following error:

[Thu Sep 09 15:44:40 2010: CRITICAL/828]: celerybeat raised exception : 'datetime.timedelta' object has no attribute 'is_due'

It then shuts down. The Celery documentation doesn't really go into what to return when making run_every a property, and I haven't had any luck searching Google. Celery changelogs say its been able to change a Periodic Task's interval at runtime since version 1.0.0.

Dev. Environment:

  • Python 2.6.5
  • Django 1.2.1
  • Celery 2.0.2
Was it helpful?

Solution

Celery 2.0 supports different schedule behaviors. There's celery.task.schedules.schedule and celery.task.schedules.crontab.

You have to return one of these, or make your own subclass of schedule.

from celery.task.schedules import schedule

@property
def run_every(self):
    if datetime.now().weekday() in [1, 2, 3]:
        return schedule(timedelta(minutes=15))
    else:
        return schedule(timedelta(seconds=40))

The run_every attribute will be automatically converted at instantiation, but not later.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top