Reputation: 119
I have a model that contains the following field
class EventConfig(models.Model):
end_date = models.DateTimeField(blank=True, null=True)
I have celery installed that's sending periodic emails and triggering other tasks at set time intervals e.g every hour or at 12pm. However, if I want to trigger an email as exactly when 'end_date' is reached, what is the best way to do this? I realise I could set a Celery schedule to run every minute to check the date, but is running a batch job every 60 seconds perpetually, the best approach or would this have drawbacks?
Is there a way for example to set the crontab schedule to read from a list of values so that I could so something like schedule_list = EventConfig.objects.all().values_list(end_date, flat=True) or schedule_list.append(self.end_date) whenever a model instance is saved, and have Celery read from 'schedule_list' so the batch jobs then only fire at the correct times?
Or is there a better way to do this either with or without celery?
Upvotes: 0
Views: 41
Reputation: 1
i think you can use Celery Beat to schedule tasks dynamically. Create a custom scheduler that reads the end_date from your EventConfig model and schedules a task accordingly.
from celery import shared_task
from celery.schedules import crontab
from celery.beat import Scheduler
class DynamicScheduler(Scheduler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.schedule = self.get_schedule()
def get_schedule(self):
schedule = {}
for config in EventConfig.objects.all():
schedule[config.id] = {
'task': 'your_task_name',
'schedule': config.end_date,
'args': (config.id,)
}
return schedule
app.conf.beat_scheduler = 'path.to.DynamicScheduler'
Upvotes: 0