How to programmatically generate celerybeat entrie

2020-05-19 05:02发布

问题:

I am hoping to be able to programmatically generate celerybeat entries and resync celerybeat when entries are added. The docs here state

By default the entries are taken from the CELERYBEAT_SCHEDULE setting, but custom stores can also be used, like storing the entries in an SQL database.

So I am trying to figure out which classes i need to extend to be able to do this.

I have been looking at celery scheduler docs and djcelery api docs but the documentation on what some of these methods do is non-existent so about to dive into some source and was just hoping someone could point me in the right direction.

I guess a high level of what I'm doing would be helpful... As a user I need to be able to select from a predefined set of tasks and provide a way for a user to select some sort of custom schedule for it to execute, like every day/week/month and what day and time.

Also this is in Django with djcelery.

UPDATE

I see the code for the djcelery admin but am not clear on how that data is being persisted. I currently have a generic addTask view that looks like this :

def addTask(request):

intervalSchedule = IntervalSchedule.from_schedule(schedule(timedelta(seconds=10)))
intervalSchedule.save()
modelData = dict(
    name="dcTestPersist",
    task="technologytrackerapi.views.createRecord",
    schedule=intervalSchedule,
)
periodicTask = PeriodicTask(**modelData)
periodicTask.save()
return render_to_response('taskView.html')

The data looks correct in the db but when the daemon runs it has this error :

[2012-03-06 00:23:07,926: WARNING/Beat] Process Beat:
[2012-03-06 00:23:07,926: WARNING/Beat] Traceback (most recent call last):
[2012-03-06 00:23:07,926: WARNING/Beat] File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
[2012-03-06 00:23:07,926: WARNING/Beat] self.run()
[2012-03-06 00:23:07,927: WARNING/Beat] File "/home/dchesterman/Documents/PythonDev/.virtualenvs/ros/local/lib/python2.7/site-packages/celery/beat.py", line 464, in run
[2012-03-06 00:23:07,927: WARNING/Beat] self.service.start(embedded_process=True)
[2012-03-06 00:23:07,927: WARNING/Beat] File "/home/dchesterman/Documents/PythonDev /.virtualenvs/ros/local/lib/python2.7/site-packages/celery/beat.py", line 403, in start
[2012-03-06 00:23:07,927: WARNING/Beat] interval = self.scheduler.tick()
[2012-03-06 00:23:07,927: WARNING/Beat] File "/home/dchesterman/Documents/PythonDev/.virtualenvs/ros/local/lib/python2.7/site-packages/celery/beat.py", line 194, in tick
[2012-03-06 00:23:07,927: WARNING/Beat] next_time_to_run = self.maybe_due(entry, self.publisher)
[2012-03-06 00:23:07,927: WARNING/Beat] File "/home/dchesterman/Documents/PythonDev/.virtualenvs/ros/local/lib/python2.7/site-packages/celery/beat.py", line 170, in maybe_due
[2012-03-06 00:23:07,927: WARNING/Beat] is_due, next_time_to_run = entry.is_due()
[2012-03-06 00:23:07,928: WARNING/Beat] File "/home/dchesterman/Documents/PythonDev/.virtualenvs/ros/local/lib/python2.7/site-packages/djcelery/schedulers.py", line 54, in is_due
[2012-03-06 00:23:07,928: WARNING/Beat] return self.schedule.is_due(self.last_run_at)
[2012-03-06 00:23:07,928: WARNING/Beat] AttributeError: 'NoneType' object has no attribute 'is_due'

I'm not sure why my schedule does not use the default is_due()

回答1:

This is what ended up working for me :

def addTask(request):

  intervalSchedule = IntervalSchedule.from_schedule(schedule(timedelta(seconds=10)))
  intervalSchedule.save()

  modelData = dict(
      name="dcTestPersist",
      task="technologytrackerapi.tasks.createRecord",
      interval_id=intervalSchedule.pk,
  )

  periodicTask = PeriodicTask(**modelData)
  periodicTask.save()

  me = ModelEntry(periodicTask)

  try:
      me.save()

  except:
    from django.db import connection
    print connection.queries
    raise

  return render_to_response('taskView.html')

I had to wrap the Periodic Task in a ModelEntry.



回答2:

I think what you want to do is add PeriodicTasks to the database. Looks like the bottom section of https://github.com/ask/django-celery/blob/master/djcelery/admin.py is how they add in tasks in the admin -- you'll need to offer something similar on the front end.