Задача, выполняемая работником сельдерея с супервизором, получающим неверное значение для datetime.date.today () - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть задача, которая периодически запускается с использованием сельдерея.И сельдерея, и сельдерей (в отдельной очереди) работают с супервизором.

Задача - сохранить дату прогона, используя функцию Python datetime.date.today().Проблема в том, что datetime.date.today() возвращает правильную дату, когда работник перезапускается, но в следующие дни, когда та же задача вызывается с использованием удара сельдерея, функция datetime.date.today() возвращает ту же дату, когда работник перезапускается вместо текущей даты.

Задача выполняется в часовом поясе utc, и я перепроверил дату выполнения.То же самое происходит, когда я пытался передать дату прогона как args, используя ритм сельдерея (в данном случае он возвращал дату начала / перезапуска такта сельдерея вместо текущей даты).Я до сих пор не могу понять, почему это происходит.Системная дата / время сервера, похоже, работают правильно.

Вот конфигурация супервизора для удара сельдерея и очереди рабочего сельдерея (это не вся конфигурация, только соответствующие блоки)

[supervisord]
logfile=/dir/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10           ; (num of main logfile rotation backups;default 10)
loglevel=info                ; (log level;default info; others: debug,warn,trac
pidfile=supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false               ; (start in foreground if true;default false)
minfds=1024                  ; (min. avail startup file descriptors;default 1024
minprocs=200                 ; (min. avail process descriptors;default 200)


[program:celery_worker_custom_queue]
environment =
    LC_ALL=en_US.UTF-8,
    LANG=en_US.UTF-8

command = /usr/local/bin/celery  --concurrency=5  -A config worker -l info -Q custom_queue -n workername@%%h
directory = /path/to/dir
priority = 2
user = user
numprocs = numprocs
stderr_logfile = log_file_path
stdout_logfile = log_file_path
autostart = true
autorestart = true


[program:celery_beat]
environment =
    LC_ALL=en_US.UTF-8,
    LANG=en_US.UTF-8

command = /usr/local/bin/celery -A config beat -l info
directory = /path/to/dir
priority = 3
user = user
numprocs = numprocs
stderr_logfile = log_file_path
stdout_logfile = log_file_path
autostart = true
autorestart = true

Я не смог найти аналогичные проблемы в Интернете, когда я проверил.Кроме того, я не могу позволить себе удалить супервизор.

Что я могу сделать в конфигурации?Кроме того, я работаю с такой установкой в ​​первый раз, я что-то упускаю концептуально?помогите пожалуйста

Редактировать: Я проверил это на моей локальной машине, она работает без супервизора.Код задачи выглядит следующим образом (удаленный код, где дата выполнения не используется)

 import datetime as dt

 run_date = (dt.date.today()).strftime('%Y-%m-%d')

 @celeryApp.task(bind=True, name="api_task",queue="custom_queue")
 def api_task(self, start_date=run_date):
   api_run_date = start_date
   #api calls and object calculations; api_run_date is not used anywhere..
   task_status(obj=status_obj, status=True, run_date=api_run_date)

 def task_status(obj, status=False, run_date=run_date):
    is_done = status
    # print(obj,' - ',run_date,' - ',is_done)
    done, created = ModelName.objects.update_or_create(date=run_date, defaults={'is_done': is_done}, obj_inst=obj)
    done.save()

1 Ответ

1 голос
/ 25 апреля 2019

Я думаю, что проблема заключается в том, как вы работаете с датой. Вы сохраняете значение datetime.date.today() в глобальной переменной run_date, а затем используете его в качестве значения по умолчанию для аргумента start_date вашей задачи. Но значения аргументов по умолчанию оцениваются только один раз, когда функция определена в Python. Поэтому, если вы фактически не предоставляете значение для start_date при вызове api_task, вы всегда работаете с одним и тем же значением. Значение является значением глобальной переменной run_date, которая, в свою очередь, оценивается только один раз при первом импорте модуля.

Правильный способ обработки это будет выглядеть так:

def api_task(self, start_date=None):
   # use `start_date` if given or current date
   api_run_date = start_date or dt.date.today().strftime('%Y-%m-%d')
   #api calls and object calculations; api_run_date is not used anywhere..
   task_status(obj=status_obj, status=True, run_date=api_run_date)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...