2015-11-23 2 views
0

У меня есть повторяющееся задание cron, которое управляет командой управления Django. Команда взаимодействует с ORM, отправляет электронную почту с помощью sendmail и отправляет SMS с Twilio. Возможно, что задания cron начнут перекрываться. Другими словами, работа (выполняющая эту команду) может все еще выполняться при запуске следующего задания. Это вызовет какие-либо проблемы? (Я не хочу ждать, пока команда управления завершит выполнение, прежде чем снова запустить команду управления cron).Перекрытие задания cron, выполняющего ту же команду управления Django: проблематично?

EDIT:

В самом начале команды управления получает временную метку, когда команда была запущена. Как минимум, эта метка времени должна быть точной. Было бы неплохо, если бы остальная часть команды не дождалась завершения предыдущего задания cron, но это не критично.

EDIT 2:

Работа хрон только считывает данные из БД, не писать в него. Приложение должно продолжать работать во время выполнения задания cron. Приложение читает и записывает из БД.

+0

Вы можете использовать стаю для этой цели. – shadow0359

ответ

1

Да. Это может вызвать проблемы. У вас есть a race condition. Если вы хотите, вы можете каким-то образом заблокировать замок на critical section, который предотвратит ввод следующего вызова из раздела кода до тех пор, пока не будет завершен первый вызов команды. Возможно, вы сможете сделать блокировку строк или блокировку таблицы для базовых данных.

Давайте предполагать, что вы используете MySQL, который имеет определенный синтаксис блокировки (DB зависимый) и у вас есть эта модель:

class Email(models.Model): 
    sent = models.BooleanField(default=False) 
    subj = models.CharField(max_length=140) 
    msg = models.TextField() 

Вы можете создать объект блокировки вроде этого:

from django.db import connection 
[...] 
class EmailLocks(object): 
    def __init__(self): 
     self.c = connection.cursor() 
    def __enter__(self): 
     self.c.execute('''lock tables my_app_email write''') 
    def __exit__(self, *err): 
     self.c.execute('unlock tables') 

Тогда блокировка все критически важных разделов, как:

with EmailLocks(): 
    # read the email table and decide if you need to process it 
    for e in Email.objects.filter(sent=False): 
     # send the email 
     # mark the email as sent 
     e.sent = True 
     e.save() 

Объект блокировки автоматически откроет таблицу при выходе. Кроме того, если вы выбросите исключение в свой код, таблица все равно будет разблокирована.

+0

Вопрос в том, какие части кода должны быть заблокированы? Есть идеи, как я могу найти ответ? – Daniel

+0

Вам нужно будет заблокировать [cricital section] (https://en.wikipedia.org/wiki/Critical_section). Я не знаю, что это будет, если вы не разместите весь свой код управления. Можно предположить, что у вас есть таблица с сообщениями для отправки, вы читаете эту таблицу, отправляете сообщения, а затем отмечаете сообщения как отправленные. Перед тем, как прочитать его, вы должны заблокировать таблицы, а затем разблокировать их после маркировки сообщения как отправленного. –

+0

Если вы не можете заблокировать запись или чтение, и только ваш процесс управления записывает «отправленный» бит (предположим снова), вы можете явно создать фиктивную таблицу для использования в блокировке. Вы должны заблокировать эту прокси-таблицу/фиктивную таблицу перед входом в критический раздел, а затем разблокировать ее после обновления реальной таблицы. –

2

Мое понимание cron заключается в том, что он будет отключаться от работы в фоновом режиме, позволяя одновременно запускать несколько заданий. Это может быть проблематично, если второе задание зависит от выполнения первого задания (если во втором выполняется ежедневный отчет об агрегированных данных, предоставленных первым заданием и т. Д.). Если вы не хотите, чтобы они запускались одновременно, есть обходные пути:

How to prevent the cron job execution, if it is already running.

Will Cron start a new job if the current job is not complete?

+0

См. Мое редактирование. Не будет ли, по крайней мере, частью этого? – Daniel

+0

Если вы спрашиваете, возможно ли, если они будут выполняться одновременно в любой момент? Да, это возможно, в зависимости от продолжительности выполнения и частоты cron. Если вы спросите, нужно ли им, чтобы они выполнялись одновременно, я бы сказал «нет», если они действительно должны запускаться одновременно по какой-то причине, я бы сказал, что они должны быть реорганизованы в 1 скрипт, чтобы убедиться, что оба блока логики выполнены по порядку. Надеюсь, что это поможет, не имеют большого понимания того, что вы на самом деле имеете. – vandsh

0

Итак, у вас есть cron, который управляет командой управления django, и вы не хотите, чтобы они перекрывались.

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

Ниже хрон я использовал:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/bin/python /home/txuser/dev/Project1/projectnew/manage.py flocktest 

Существует гораздо больше вы можете сделать с этим. more on this

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