Можно ли добавить конфигурацию 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, а затем установив новую конфигурацию.

  1. Вызов yaws_api:getconf/0 получить 3-кортеж {ok, GlobalConf, ServerConfs} где GlobalConf это глобальная конфигурация Yaws и ServerConfs список списков конфигураций сервера Yaws Глобальный conf - это тип записи с именем gconf и сервер conf является типом записи с именем sconf; оба эти типа записей определены в yaws.hrl заголовочный файл
  2. Пройдите через настройки сервера, чтобы найти тот, который содержит appmods, который вы хотите изменить. Это немного сложно, потому что вы имеете дело со списком списков, и вам нужно сохранить форму общей структуры данных без изменений.
  3. Как только вы найдете sconf, создать новый sconf Например, добавив новый appmod в текущий список appmods. Каждый элемент списка appmod представляет собой кортеж, состоящий из URL-пути для appmod и имени модуля appmod. Кортеж appmod может также дополнительно содержать третье поле, состоящее из списка путей в первом пути, который должен быть исключен; см. описание exclude_paths в документации по appmod для более подробной информации.
  4. Заменить существующий sconf значение в ServerConfs с вашей новой ценностью.
  5. Вызов 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 запись доступна.

Другие вопросы по тегам