вторник, 15 декабря 2009 г.

RESTAS-daemon

Ранее я рассказывал, как можно написать демона на "pure lisp" и таким образом обойтись без граблей в виде Screen или detachtty. С тех пор, у меня развелось некоторое колличество подобных демонов для разных сервисов, с общим базовым кодом и незначительными отличиями. Я использовал технику copy/paste, что меня сильно огорчало, да и неудобства заметные - время от времени я правлю базовый код и изменения надо руками разносить по разным файлам (на разных серверах). Желание сделать некую общую схему с повторным использованием у меня было с самого начала, но вот сделать универсальный "демонизатор" не так просто. В итоге, я решил отказаться от универсального решения, и сделать скрипт для запуска как демонов web-приложений на базе RESTAS. Это довольно просто, ибо все эти приложения запускаются однотипно: загрузить нужную asdf-систему и вызвать restas:start-site с именем сайта, определенным с помощью макроса restas:defsite. Получившийся скрипт я назвал restas-daemon.lisp и положил в директорию contrib пакета RESTAS. Теперь запустить демона для web-приложения на базе RESTAS очень просто:
sbcl --noinform --no-userinit --no-sysinit --load /path/to/restas/contrib/restas-daemon.lisp /path/to/daemon.conf COMMAND
Как видно, данный скрипт принимает два параметра: путь к файлу конфигурации демона и имя команды. Поддерживаются следующие команды:
  • start - запуск
  • stop - остановка
  • restart - рестарт
  • kill - убийство, если почему-то демон не хочет останавливаться с помощью stop
  • zap - удалят pid-файл, это может потребоваться, если демон был остановлен как-нибудь грубо
  • nodaemon - в основном тоже, что и start (в том числе происходит смена прав и т.п.), но при этом процесс не делает себе fork и не отключается от терминала, что даёт возможность наблюдать весь его вывод - удобно для отладки демона.
Файл конфигурации демона может содержать определение нескольких переменных, влияющих на поведение демона, вот полный конфиг моего домашнего демона:
(defparameter *name* "homesite")

(defparameter *user* "andrey")

(defparameter *swankport* 9000)

(defparameter *asdf-central-registry*
'(#P"/usr/share/common-lisp/systems/" #P"/home/andrey/development/common-lisp/common-lisp-systems/"))

(defparameter *asdf-load-systems* '(#:homesite))

(defparameter *sites* '((#:homesite nil 80)))
Возможны следующие параметры:
  • *name* - имя демона, в данный момент единственный обязательный параметр
  • *user* - имя пользователя, от которого должен работать демон, по-умолчанию совпадает с именем демона
  • *group* - группа пользователя
  • *fasldir* - путь к каталогу, в который будут складываться fasl-файлы, по-умолчанию определяется из имени демона как (format nil "/var/cache/~A/fasl/" *name*)
  • *pidfile* - pid-файла демона, по-умолчанию (format nil "/var/run/~A/~A.pid" *name* *name*)
  • *swankport* - порт, на котором следует запускать swank, если не указан или nil, то swank не запускается
  • *default-host-redirect* - в RESTAS сайты запускаются с помощью restas:start-site, при этом можно указать имя хоста (аналог виртуальных хостов), данная переменная указывает хост, на который будет производиться редирект, если для хоста запроса нет сайта, например, на lisper.ru можно попасть набрав в браузере www.lisper.ru, lisp.catap.ru или просто прямой адрес, все такие запросы перенаплавляются на lisper.ru
  • *asdf-central-registry* - список директорий, в которых будет производиться поиск систем
  • *asdf-load-systems* - список систем, которые необходимо загрузить при старте демона
  • *sites* - список сайтов, которые необходимо запустить при запуске демона с помощью функции restas:start-site. В качестве сайта может быть указано просто имя, либо список, например '(#:rulisp "lisper.ru" 80). Сайты определяются с помощью restas:defsite - это происходит при загрузке указанных asdf-систем.
Для систем на базе Gentoo есть специальная поддержка. При установке restas с помощью моего форка gentoo-lisp-overlay в каталог /etc/init.d/ добавляется скрипт restas.lo. Теперь, для создания initd-скрипта необходимо создать симлинк на этот файл и создать конфигурационный файл в /etc/conf.d/, например:
cd /etc/init.d/
ln -s restas.lo homesite
emacs /etc/conf.d/homesite.conf
/etc/init.d/homesite start
Схема может быть ещё не совсем устоявшаяся, но уже рабочая :)

Комментариев нет:

Отправить комментарий