Можно ли добавить конфигурацию YAWS appmods во время выполнения?
Я встроил YAWS в свое приложение в производственной среде, и я использую функцию yaws:start_embedded/4
начать YAWS.
Ниже мой код:
Id = "my_server",
GconfList = [{logdir, "./log"}, {id, Id}],
SconfList = [{docroot, Docroot},
{port, Port},
{listen, Listen},
{appmods, [
{"/rest", mod_rest, []},
{"/file", mod_file, []}
]}
],
yaws:start_embedded(Docroot, SconfList, GconfList, Id).
Я хотел бы добавить еще один appmod, например: {"/upload", mod_upload, []}
Можно ли добавить appmods во время выполнения без перезапуска YAWS?
1 ответ
Вы можете добавить appmods во время выполнения, сначала получив текущую конфигурацию, используя ее для создания новой конфигурации, содержащей ваши новые appmods, а затем установив новую конфигурацию.
- Вызов
yaws_api:getconf/0
получить 3-кортеж{ok, GlobalConf, ServerConfs}
гдеGlobalConf
это глобальная конфигурация Yaws иServerConfs
список списков конфигураций сервера Yaws Глобальный conf - это тип записи с именемgconf
и сервер conf является типом записи с именемsconf
; оба эти типа записей определены вyaws.hrl
заголовочный файл - Пройдите через настройки сервера, чтобы найти тот, который содержит appmods, который вы хотите изменить. Это немного сложно, потому что вы имеете дело со списком списков, и вам нужно сохранить форму общей структуры данных без изменений.
- Как только вы найдете
sconf
, создать новыйsconf
Например, добавив новый appmod в текущий список appmods. Каждый элемент списка appmod представляет собой кортеж, состоящий из URL-пути для appmod и имени модуля appmod. Кортеж appmod может также дополнительно содержать третье поле, состоящее из списка путей в первом пути, который должен быть исключен; см. описаниеexclude_paths
в документации по appmod для более подробной информации. - Заменить существующий
sconf
значение вServerConfs
с вашей новой ценностью. - Вызов
yaws_api:setconf/2
установить новую конфигурацию, передав существующуюGlobalConf
в качестве первого аргумента и новогоServerConfs
содержащий ваш новыйsconf
как второй аргумент.
am_extend
Модуль ниже показывает, как это сделать. Это экспортирует add/1
функция, которая принимает функцию, которая может идентифицировать и дополнять appmods на конкретном сервере, который вам нужен.
-module(am_extend).
-export([add/1]).
add(AppmodAdder) ->
{ok, GlobalConf, ServerConfs} = yaws_api:getconf(),
NewServerConfs = add_appmod(ServerConfs, AppmodAdder),
yaws_api:setconf(GlobalConf, NewServerConfs).
add_appmod(ServerConfs, AppmodAdder) ->
lists:foldl(fun(Val, Acc) ->
Acc ++ [AppmodAdder(A) || A <- Val]
end, [], ServerConfs).
Примером использования этого кода является передача функции ниже как AppmodAdder
аргумент в пользу am_extend:add/1
, Для этого примера мы ищем сервер, который имеет путь appmod "/sse"
так что мы можем добавить еще один appmod на этот сервер для пути "/sse2"
, Любой серверный конф, о котором мы не заботимся, просто возвращается без изменений.
-include_lib("yaws/include/yaws.hrl").
add_sse2(#sconf{appmods=AM}=SC) ->
case lists:keyfind("/sse", 1, AM) of
false ->
SC;
_ ->
SC#sconf{appmods=[{"/sse2", my_sse_module}|AM]}
end.
Обратите внимание, что наш add_sse2/1
функция должна быть скомпилирована с yaws.hrl
так что у него есть определение для sconf
запись доступна.