У меня есть длительный процесс, который должен запускаться каждые пять минут, но более одного экземпляра процессов никогда не должны запускаться одновременно. Обычно процесс не должен длиться более пяти минут, но я хочу быть уверенным, что второй экземпляр не запустится, если он завершится.
Согласно предыдущей рекомендации , я использую Django Celery для планирования этой длительной задачи.
Я не думаю, что периодическая задача будет работать, потому что, если у меня есть пятиминутный период, я не хочу, чтобы вторая задача выполнялась, если другой экземпляр задачи уже запущен.
Мой текущий эксперимент выглядит следующим образом: в 8:55 запускается экземпляр задачи. Когда задача завершается, она запускает другой собственный экземпляр на следующей пятиминутной отметке. Таким образом, если первая задача завершилась в 8:57, вторая задача будет запущена в 9:00. Если первая задача выполняется долго и завершается в 9:01, запуск следующего экземпляра запланирован на 9:05.
Я боролся с множеством загадочных ошибок, когда делал что-то большее, чем простой пример ниже, и я не нашел других примеров, когда люди планировали задачи из предыдущего экземпляра самого себя. Мне интересно, может быть, есть лучший подход к тому, что я пытаюсь сделать.Я знаю, что есть способ назвать свои задачи; возможно, есть способ поиска запущенных или запланированных экземпляров с тем же именем? Есть ли у кого-нибудь совет относительно запуска задачи каждые пять минут, но с одновременным выполнением только одной задачи?
Спасибо, Джо
В mymodule / tasks.py:
import datetime
from celery.decorators import task
@task
def test(run_periodically, frequency):
run_long_process()
now = datetime.datetime.now()
# Run this task every x minutes, where x is an integer specified by frequency
eta = (
now - datetime.timedelta(
minutes = now.minute % frequency , seconds = now.second,
microseconds = now.microsecond ) ) + datetime.timedelta(minutes=frequency)
task = test.apply_async(args=[run_periodically, frequency,], eta=eta)
Из оболочки ./manage.py:
from mymodule import tasks
result = tasks.test.apply_async(args=[True, 5])