блоки подпроцесса Django view - PullRequest
       6

блоки подпроцесса Django view

2 голосов
/ 01 февраля 2011

У меня проблема с вызовом подпроцесса. Открыть из представления: Представление, которое вызывает subprocess.Popen, не отображается, пока подпроцесс не завершится. Сервер немедленно отправляет «200 OK», но не содержимое страницы.

Мой вопрос: это ограничение сервера разработки Django или я делаю это неправильно?

Сервер не полностью зависает, поскольку в это время могут быть обработаны другие представления.

Уже есть несколько вопросов по этой теме , и Google дает несколько других тем , но я не могу найти четкий ответ на свой вопрос.

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

python -c 'import subprocess; print subprocess.Popen (["/ bin / sleep", "10"]). pid '

Как воспроизвести

Создание тестового проекта и приложения:

cd / tmp
django-admin.py startproject django_test
cd django_test
./manage.py startapp subprocess_test

Заменить urls.py & subprocess_test / views.py на:

  • urls.py:

    из django.conf.urls.defaults import *

    urlpatterns = Patterns ('',
    (r '^ hello $', 'subprocess_test.views.hello'),
    (r '^ start $', 'subprocess_test.views.start'),
    )

  • subprocess_test / views.py

    из django.http import HttpResponse

    подпроцесс импорта

    def привет (запрос):
    return HttpResponse ('Привет, мир!')

    def start (запрос):
    subprocess.Popen (["/ bin / sleep", "10"])
    return HttpResponse ('начало выполнено')

Проверьте это:

. / Manage.py runserver 0.0.0.0:8000

Перейти к http://127.0.0.1:8000/hello и http://127.0.0.1:8000/start

Результат теста

«запуск» занимает 10 секунд для загрузки и «привет» может быть загружен в течение этого времени. Например, я получаю такой журнал:

[01 / Feb / 2011 07:20:57] "GET / привет HTTP / 1.1" 200 12
[01 / Feb / 2011 07:21:01] «GET / start HTTP / 1.1» 200 10
[01 / Feb / 2011 07:21:01] "GET / привет HTTP / 1.1" 200 12
[01 / Feb / 2011 07:21:02] "GET / привет HTTP / 1.1" 200 12

Использование wget:

wget http://127.0.0.1:8000/start
--2011-02-01 14: 31: 11-- http://127.0.0.1:8000/start
Подключение к 127.0.0.1:8000 ... подключено.
HTTP-запрос отправлен, ожидание ответа ... 200 OK
Длина: не указано [текст / html]
Сохранение в: `start '

[           <=>                           ] 10          --.-K/s   in 9,5s    

2011-02-01 14:31:21 (1,05 Б / с) - «старт» сохранен [10]

Ответы [ 3 ]

3 голосов
/ 01 февраля 2011

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

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

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

Трафик может не быть проблемой, но я лично считаю, что это более чистое решение для дизайна.

2 голосов
/ 26 июня 2011

Я столкнулся с той же проблемой при запуске Django с nginx + uwsgi. Зачастую переломным моментом является модуль веб-сервера, в моем случае это был uwsgi . Добавление <close-on-exec/> решило эту проблему. С другой стороны, модуль fastcgi не позволяет просматривать зависшие на фоновых процессах.

Я не знаю, какой сервер вы используете, поэтому вы можете проверить это поведение с помощью различных модулей (uwsgi, mod_wsgi, fastcgi) и посмотреть, что вам больше подходит. И попробуйте выполнить в фоновом режиме:

subprocess.Popen(["/bin/sleep", "10", "&"])
0 голосов
/ 01 февраля 2011

Попробуйте это

import subprocess

x = subprocess.Popen(["/bin/sleep", "10"])
x.wait()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...