是否可以在运行时添加YAWS appmods配置?

che*_*hao 2 erlang yaws

我在生产环境中的应用程序中嵌入了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).
Run Code Online (Sandbox Code Playgroud)

我想添加另一个appmod,例如: {"/upload", mod_upload, []}

是否可以在运行时添加appmod而无需重新启动YAWS?

Ste*_*ski 5

您可以在运行时添加appmod,方法是首先检索当前配置,使用它来创建包含新appmods的新配置,然后设置新配置.

  1. 调用yaws_api:getconf/0获取3元组{ok, GlobalConf, ServerConfs},其中GlobalConf是全局Yaws配置,并且ServerConfs是Yaws服务器配置列表的列表.全局conf是一个名为的记录类型gconf,服务器conf是一个名为的记录类型sconf; 这两种记录类型都在yaws.hrl头文件中定义.
  2. 完成服务器配置以查找包含要更改的appmod的配置.这有点棘手,因为您正在处理列表列表,并且您需要保持整体数据结构的形状不变.
  3. 找到后sconf,sconf通过将新的appmod添加到其当前的appmod列表中,从中创建一个新实例.appmod列表的每个元素都是一个元组,由appmod的URL路径和appmod模块的名称组成.appmod元组还可以选择性地包含第三个字段,该第三个字段由要排除的第一个路径下的路径列表组成; 看到的描述exclude_paths的雅司病appmod文件的更多细节.
  4. 替换现有sconf的价值ServerConfs和你的新价值.
  5. 调用yaws_api:setconf/2设置新配置,将existing GlobalConf作为第一个参数传递,ServerConfs将new sconf作为第二个参数传递给new .

am_extend下面的模块显示了如何执行此操作.它导出一个add/1函数,该函数接受一个函数,该函数可以识别和扩充​​您关心的特定服务器中的appmod.

-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).
Run Code Online (Sandbox Code Playgroud)

使用此代码的一个示例是将以下函数作为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.
Run Code Online (Sandbox Code Playgroud)

请注意,我们的add_sse2/1函数必须使用yaws.hrlincluded 编译,因此它具有sconf可用记录的定义.