Mod_wsgi: обновить код через Inotify - не каждые N секунд

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

https://code.google.com/archive/p/modwsgi/wikis/ReloadingSourceCode.wiki

Это имеет недостаток, что изменения кода обнаруживаются только каждые N секунд. Я мог бы использовать N = 0,1, но это приводит к бесполезному диску IO.

AFAIK обратный вызов inotify ядра linux доступен через python.

Есть ли более быстрый способ обнаружить изменения кода и перезапустить обработчик wsgi?

Мы используем режим демон в linux.

Почему перезагрузка кода для mod_wsgi вообще

Есть интерес к тому, почему я хочу этого вообще. Вот моя настройка:

Большинство людей используют "manage.py runserver" для разработки и некоторые другие wsgi развертывание для производства.

В моем контексте мы автоматизировали создание новых систем, а системы prod и development в основном идентичны.

Одна операционная система (linux) может принимать N-системы (виртуальные среды).

Разработчики могут использовать runerver или mod_wsgi. Использование runerver имеет то преимущество, что легко отлаживать, mod_wsgi имеет то преимущество, что вам не нужно сначала запускать сервер.

mod_wsgi имеет преимущество, что вы знаете URL: https://dev-server/system-name/myurl/

С сервером-сервером вы не знаете порт. Случай использования: вы хотите связать внутреннюю wiki с dev-system....

Грязный взломать перезагрузку кода для mod_wsgi, который мы использовали в прошлом: maximum-requests=1, но это медленно.

Ответ 1

прелюдий.

Разработчики могут использовать runerver или mod_wsgi. Использование сервера что вам легко отлаживать, mod_wsgi имеет преимущество, которое вам не нужно сначала запускать сервер.

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

Если вы работаете на порту 80 или 443, что обычно происходит, сервер может быть запущен только корневым. Если его нужно перезапустить, вам придется снова попросить помощь суперпользователя. Итак, ./manage.py runserver сильно забивает здесь.

mod_wsgi имеет то преимущество, что вы знаете URL: https://dev-server/system-name/myurl/

Что ничем не отличается от dev-сервера. По умолчанию он начинается с порта 8000, поэтому вы можете получить к нему доступ как http://dev-server:8000/system-name/myurl/. Если вы хотите использовать SSL с сервером разработки, вы можете использовать пакет, например django-sslserver, или вы можете поставить nginx перед сервером разработки django.

С сервером-сервером вы не знаете порт. Случай использования: вы хотите связать из > внутренней вики с dev-системой....

С сервером-сервером порт хорошо определен, как указано выше. И вы можете заставить его слушать другой порт для exapmle с помощью:

 ./manage.py runserver 0.0.0.0:9090

Обратите внимание, что если вы поставили сервер разработки за Apache (как обратный прокси) или NGINX, проблемы с перезапуском и т.д., о которых я упоминал выше, здесь не применяются.

Итак, для разработки, что вы делаете с mod_wsgi, можно сделать с сервером разработки django (он же. /manage.py runningerver).

Inotify

Здесь мы добираемся до главной темы. Предполагая, что вы установили inotify-tools, вы можете ввести это в свою оболочку. Вам не нужно писать script.

  while inotifywait -r -e modify .; do sudo kill -2 yourpid ; done

Это приведет к перезагрузке кода, когда...

... используя режим демона с помощью одного процесса, вы можете отправить SIGINT сигнал к процессу демона с помощью команды "kill" или приложение отправляет сигнал самому себе, когда конкретный URL-адрес срабатывает. ref: http://modwsgi.readthedocs.io/en/develop/user-guides/frequently-asked-questions.html#application-reloading

в качестве альтернативы

while inotifywait -r -e modify .; do touch wsgi.py ; done

когда

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

В обеих ситуациях мы используем флаг -r, чтобы сообщить inotify для мониторинга подкаталогов. Это означает, что каждый раз, когда вы сохраняете файл .css или .js, apache перезагружается. Но без изменения флага -r для кода python в подпапках не обнаружено. Чтобы иметь лучшее из обоих направлений, удалите css, js, images и т.д. С помощью директивы --exclude.

Как насчет того, когда ваша среда IDE сохраняет файл автозагрузки? или vim сохраняет файл .swp? Это также вызовет перезагрузку кода. Поэтому вам также придется исключать эти типы файлов.

Итак, коротко, много тяжелой работы, чтобы воспроизвести, что делает сервер разработки django бесплатно.

Ответ 2

Вы можете использовать inotify hooktables для запуска любой команды, которую вы хотите, в зависимости от сигнала i-notify (здесь ссылка на источник: http://terokarvinen.com/2016/when-files-change-take-action-inotify-hookable).

После просмотра таблиц вы можете просто перезагрузить код apache.

Для вашей конкретной проблемы это должно быть примерно так:

inotify-hookable --watch-directories sources/ --recursive --on-modify-command './code_reload.sh'

В предыдущей ссылке команда для выполнения была просто простой touch flask/init.wsgi

Итак, весь код (добавление игнорируемых файлов было):

inotify-hookable --watch-directories flask/ --recursive  --ignore-paths='flask/init.wsgi' --on-modify-command 'touch flask/init.wsgi'

Как указано здесь: Автоматическая перезагрузка Flask + mod_wsgi при изменении исходного кода, , если вы включили WSGIScriptReloading, вы можете просто коснуться этот файл. Это приведет к перезагрузке всего кода (а не только к файлу конфигурации). Но, если вы предпочитаете, вы можете установить любой другой script, чтобы перезагрузить код.

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