Собираем
информацию
по крупицам
Статьи - Компьютерное

Web - разработка

Django: как применить изменения в исходниках проекта на Apache-2 и WSGI
06-11-2013
22:40:21

В процессе изучения фреймверка Django, я так и не смог найти вменяемого ответа на русском языке о том, как же обновлять проект после изменения в исходных файлах. Да, это известная проблема - если разработка ведется под Apache-2 с использованием mod_wsgi, то изменения, внесенные в исходники, не применяются. На первых порах программисты просто перезапускают Apache, но, конечно, это неправильный путь.

 

Здесь я привожу вольный перевод статьи Reloading Source Code (Перезагрузка исходного кода), взятой из базы знаний проекта WSGI.

 

* * *

 

Этот документ содержит информацию о механизме, позволяющем в Apache-модуле mod_wsgi производить автоматическое обновление (перезагрузку) исходного кода скриптов в случае, если они были изменены. Также здесь описываются возможные проблемы и пути решения. Все нижеприведенные сведения актуальны для mod_wsgi v. 2.x.

 

 

Отличия "встраиваемого режима" и "режима демона"

 

Механизм автоматической перезагрузки кода зависит от того, в каком режиме работает WSGI-приложение.

 

Если ваше WSGI-приложение запускается во встраеваемом режиме (embedded mode), тогда Апач самостоятельно работает с процессами, обслуживающими HTTP-запросы. В общем случае, если у вас используется встраиваемый режим, у вас не остается выбора - вы должны перезапускать Апач, и никак иначе. Перезапускать можно вручную, или автоматизировать этот процесс.

 

Если вы используете режим демона (daemon mode), тогда mod_wsgi работает напрямую с процессами, обслуживающими HTTP-запросы. И так как ваше WSGI-приложение запущено, оно может инициировать автоматическую перезагрузку исходного кода.

 

Поэтому перво-наперво надо выяснить, в каком режиме запускается ваше WSGI-приложение.

 

Если вы точно не знаете, в каком режиме запускается WSGI-приложение, нужно сделать следующее:

 

1. В питоновском WSGI-скрипте (обычно это django.wsgi) закомментировать строку:

 

application = django.core.handlers.wsgi.WSGIHandler()

 

2. Добавить следующий код:

 

def application(environ, start_response):
  status = '200 OK'

  if not environ['mod_wsgi.process_group']:
    output = 'EMBEDDED MODE'
  else:
    output = 'DAEMON MODE'

  response_headers = [('Content-Type', 'text/plain'),
    ('Content-Length', str(len(output)))]

  start_response(status, response_headers)

  return [output]

 


Открыв корневой URL вашего приложения, вы увидите строку "EMBEDDED MODE" или "DAEMON MODE".

 

 

Перезагрузка во встраиваемом режиме

 

Когда вы подключаете WSGI-обработчик к Апачу, вы создаете файл скрипта, в котором находится точка входа вашего WSGI-обработчика. Этот файл скрипта работает не как обычный модуль Питона, и даже не обязан использовать расширение ".py".

 

... дальше идут пространные размышления о том, что приложение Django состоит не только из исходников, написанных пользователем, но и из подключаемых Python-модулей. И поэтому, и в силу прочих причин, нет никакой возможности на лету определять где что изменилось, и к тому же в Апаче вроде как не предусмотрен механизм перезагрузки только того что изменилось. В общем все плохо настолько, что даже если и попытаться сделать реакцию на изменение исходника, то нужно не забывать, что такой исходник надо подключать не просто через import, а через import с проверкой подгруженных модулей, чтобы один и тот же модуль при обновлении не подгрузился по второму разу...

 

Вывод следующий - просто так в во встраиваемом режиме перезагрузку исходников не сделаешь.

 

 

Перезапуск Апач-процесса

 

Таки как же перезагрузить исходники во встраиваемом режиме? Есть один способ. Способ жуткий и неудобный, но ничего лучшего не придумано (хотя говорят, что вроде как код все-таки перегружается, если обновляется wsgi-скрипт).

 

Способ заключается в следующем. Необходимо в настройках Апача установить директиву MaxRequestsPerChild в значение 1:

 

MaxRequestsPerChild 1

 

Такая настройка будет перезапускать процесс-воркер Апача после каждого HTTP-запроса. Перезапуск будет происходить даже если вы не изменили ничего в коде.

 

Перезагрузка будет происходить всегда - и для GET, и для POST запросов. Кратко говоря, использовать такой метод не рекомендуется. А другого нет.

 

Поэтому, ничего не остается, как переводить WSGI-приложение в режим реботы в виде демона. А еще можно извратиться, и сделать работу WSGI-приложения через CGI/WSGI мост. К сожалению, что такое "CGI/WSGI мост", в данной статье не объясняется.

 

 

Перезагрузка в режиме демона

 

Нафига я это перевожу? У меня все равно EMBEDDED MODE.

 



К списку "Компьютерное"

Поделиться этой страницей


Статистика


RSS подписка

Подпишитесь на новости сайта по RSS


 WebHamster.Ru
 Домик любопытного хомячка
Яндекс индекс цитирования
Почтовый ящик