2016-11-16 8 views
3

Я встроил YAWS в свое приложение в производственной среде, и я использую функцию yaws:start_embedded/4 для запуска YAWS.Можно ли добавить конфигурацию appmods 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?

ответ

6

Вы можете добавить appmods во время выполнения, сначала извлекая текущую конфигурацию, используя ее, чтобы создать новую конфигурацию, содержащую ваши новые приложения, и затем установить новую конфигурацию.

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

Модуль am_extend ниже показывает, как это сделать. Он экспортирует функцию add/1, которая выполняет функцию, которая может идентифицировать и расширять приложения на определенном сервере, о котором вы заботитесь.

-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). 

Пример использования этого кода, чтобы передать функцию ниже в качестве аргумента для AppmodAdderam_extend:add/1. В этом примере мы ищем сервер, который имеет путь appmod "/sse", поэтому мы можем добавить еще одно приложение на этот сервер для пути "/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 записи доступны.

+1

Я пробовал код, который вы предоставляете, и он работает, и не будет влиять на другое подключенное соединение, большое вам спасибо! – chengweichao