2014-02-17 3 views
1

Я использую изюминку из сельдерея, чтобы запланировать некоторые задачи. Я могу использовать параметр CELERY_TIMEZONE для планирования задач с использованием графика crontab, и он запускается в запланированное время в указанном часовом поясе.Порошок сельдерея - другой часовой пояс за задание

Но я хочу иметь возможность настраивать несколько таких задач для разных часовых поясов в одном приложении (один django settings.py). Я знаю, какая задача должна выполняться в какой часовой пояс при планировании задачи.

Можно ли указать другой часовой пояс для каждой из задач?

Я использую django (1.4) с сельдереем (3.0.11) и сельдереем django (3.0.11).

Я изучил класс djcelery.schedulers.DatabaseScheduler, и это базовый класс, но я не могу понять, как и где используется часовой пояс. Могу ли я написать собственный планировщик, который может выполнять каждое задание в другом часовом поясе?

Спасибо,

ответ

1

Я думаю, что самый простой способ сделать это состоит в использовании декоратора с mock

from mock import patch 

@task 
@patch.multiple(settings, CELERY_TIMEZONE='time_zone') 
def my_task(*args): 
    #do your staff 

Я не проверял еще, но это кажется правильным. Надеюсь, я помог вам :)

+0

Спасибо за предложение. Позвольте мне попробовать. Я думал, что это нужно, но не знал о насмешливости. – ksrini

+0

Чтобы подумать об этом сейчас, часовой пояс должен быть исправлен, когда начнется бит, а не когда задача будет выполнена, я бы подумал. Я собираюсь проверить это. – ksrini

+0

У меня такая же ситуация, вы придумали что-нибудь еще? – reptilicus

0

Возможно, я не понимаю проблему, но если вы хотите запускать задачи в определенное время в разных часовых поясах, не могли бы вы просто компенсировать запланированное время на часовую разницу между временем зоны? Например, если бы я хотел, чтобы запустить задачу в 5 вечера в двух разных TZS:

# settings.py 
CELERY_TIMEZONE = "US/Eastern" 

CELERYBEAT_SCHEDULE = { 
    # Task to run in EST 
    'schedule-my-est-task': { 
     'task': 'path.to.my.est.task', 
     'schedule': crontab(minute=0, hour=17), 
    }, 
    # Task to run in UTC - hour time is offset 
    'schedule-my-utc-task': { 
     'task': 'path.to.my.utc.task', 
     'schedule': crontab(minute=0, hour=10), 
    }, 
} 
+1

На самом деле это именно то, чего я пытаюсь избежать. В настоящее время это то, что делается. Но каждый раз, когда происходит изменение параметров дневного света, кто-то должен менять расписание. Пользователи добавят расписание, используя консоль администратора, например интерфейс, и укажу часовой пояс (на самом деле это место, и я определяю часовой пояс для этого). Я хочу, чтобы пользователь установил расписание для часового пояса и забыл об этом и не беспокоился об изменении расписания при изменении настроек дневного света. – ksrini

+0

Это имеет смысл и затрудняет проблему с оригиналом. Итак, вы хотите, чтобы задача выполнялась в определенное время на основе чей-то часового пояса, чтобы они могли изменять часовой пояс и все же получать его одновременно в любой временной зоне, в которой они находятся? Возможно, вы можете запускать еще одну запланированную задачу каждый час и каждый час, проверять пользователей в часовом поясе, где в данный момент времени вы хотите, чтобы ваша задача выполнялась. Тогда вы можете запустить исходную задачу из запланированной задачи только для соответствующих пользователей? –

7

Вы можете достигнуть временной зоны планирования, осведомленного отдельных задач в расписании сельдерея. Таким образом, вы можете запустить задачу по местному времени в определенном часовом поясе (также приспосабливаясь к, например, летнее время) с помощью указания отдельного теперь работает для каждого графика сельдерея

crontab поддерживает nowfun argument указать функцию DATETIME который будет использоваться, чтобы проверить, если он должен работать

import datetime 
import pytz 
nowfun = lambda: datetime.datetime.now(pytz.timezone('Europe/Berlin')) 

в расписании, установите эту функцию в качестве функции даты и времени с помощью

'periodic_task': { 
    'task': 'api.tasks.periodic', 
    'schedule': crontab(hour=6, minute=30, nowfun=nowfun) 
} 

Это работает каждый день в 6:30 утра по понедельникам, с поправкой на летнее время.

В случае, если вы используете функцию более чем один раз, рассмотреть вопрос о создании помощника

from functools import partial 
cet_crontab = partial(crontab, nowfun=nowfun) 
'periodic_task': { 
    'task': 'api.tasks.periodic', 
    'schedule': cet_crontab(hour=6, minute=30) 
} 

Убедитесь, что вы CELERY_ENABLE_UTC = False набор, в противном случае сельдерей преобразует ваши графики в формате UTC.

Смежные вопросы