2013-11-23 4 views
2

Я знаю, что есть много вопросов, подобных этому, но насколько мое исследование заняло меня, никто из них не отвечает на мой конкретный вопрос. Надеюсь, вы потратите свое время, чтобы помочь мне, поскольку я боролся с этим в течение многих дней, не найдя подходящего ответа.Лучший способ реализовать длительный подпроцесс в Django?

Я пытаюсь найти лучший способ реализовать подпроцесс в приложении Django. Точнее:

  • Процесс будет выполняться с одного вида (асинхронно) и обрабатываться другим.
  • Процесс может занять до нескольких часов.
  • Несколько экземпляров одного и того же процесса/программы должны работать одновременно.
  • Помимо знания того, когда процесс завершен (или если он разбился, чтобы его можно было запустить повторно), общение с ним не требуется.

Кто-нибудь знает, каким образом было бы лучше всего реализовать это? Может ли какой-либо из модулей Python (таких как subprocess, threads, multiprocessing, spawn) достичь этого или мне придется реализовать внешнюю очередь задач, такую ​​как Celery?

+5

Я уверен, что это достижимо другими способами, но сельдерей (или другая внешняя очередь задач), безусловно, является лучшим вариантом. –

+0

@ LudwikTrammer Спасибо! Вы порекомендовали бы сельдерей или другую внешнюю очередь задач? – Banana

+1

Рассматривайте это еще одно голосование за сельдерей. – erewok

ответ

1

Похоже, что большинство людей рекомендуют Celery, а после использования в течение нескольких месяцев я могу только согласиться. Time limits, concurrent processes limits и task scheduling - это лишь некоторые из функций, которые я нашел удобными.

Кроме того, при запуске на сервере Celery Flower - отличный плагин для отслеживания процессов извне.

2

Если вы не хотите что-то так сложно, как сельдерей, то вы можете использовать subprocess + nohup начать длительные задания от, сбросить PID в файл (проверьте subprocess документации для того, как сделать это), а затем проверить если PID, содержащийся в файле, все еще работает (с использованием ps). И если вы этого захотите, вы можете написать очень маленький сценарий «обертка», который будет запускать задачу, о которой вы ему рассказываете, и если он сработает, напишите файл «crashed.txt».

Следует отметить, что вы должны, вероятно, запускать команды, включая значение close_fds=True для вызова. (так check_call(['/usr/bin/nohup', '/tasks/do_long_job.sh'], close_fds=True)). Зачем? По умолчанию всем подпроцессам предоставляется доступ к дескрипторам открытых файлов родителя, ВКЛЮЧАЯ порты. Это означает, что если вам нужно перезапустить процесс веб-сервера, в то время как длительный процесс выполняется, то запущенный процесс будет поддерживать открытие порта, и вы не сможете снова загрузить сервер. Вы можете догадаться, как я это узнал. :-)

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