ejabberd_config

ejabberd的config模块

-record(state,
    {opts = []               :: [acl:acl() | local_config()],
         hosts = []              :: [binary()],
         override_local = false  :: boolean(),
     override_global = false :: boolean(),
         override_acls = false   :: boolean()}).
View Code
-callback opt_type(atom()) -> function() | [atom()].

如果要behaviour这个模块 则要实现 opt_type方法

ejabberd_config:start   创建local_config 数据表,读取配置文件

读取顺序为:1、application:get_env(config)

      2、application:get_env(ejabberd, file)

      3、os:getenv("EJABBERD_CONFIG_PATH")  默认的此为 "//etc/ejabberd/ejabberd.yml"

      4、CONFIG_PATH -> <<"ejabberd.cfg">>

然后根据配置文件路径读取(read_file):

      读取过程中会分析文件的路径(相对或者绝对、filename:pathtype),用到了filename、file模块

      然后进行到consult 方法  1、如果配置文件为.yml .yaml结尾则利用p1_yaml:decode_from_file方法(p1_yaml为项目的扩展application)

      

-module(p1_yaml).

decode_from_file(File, Opts) ->
    case file:read_file(File) of
        {ok, Data} ->
            decode(Data, Opts);
        Err ->
            Err
    end.

decode(Data, Opts) ->
    nif_decode(Data, make_flags(Opts)).
View Code

                  可以看到最后的nif_decode方法进入了c的扩展

static ErlNifFunc nif_funcs[] =
    {
    {"nif_decode", 2, decode}
    };
View Code

                  然后利用parserl方法解析

                  2、其他的则为file:consult,利用file模块的consult方法读取

      读取后根据include_modules_configs参数决定是否加在扩展模块的配置文件(默认开启)

      则要执行以下代码

Files = [{filename:rootname(filename:basename(F)), F}
                                     || F <- filelib:wildcard(ext_mod:config_dir() ++ "/*.{yml,yaml}")
                                          ++ filelib:wildcard(ext_mod:modules_dir() ++ "/*/conf/*.{yml,yaml}")],
                            [proplists:get_value(F,Files) || F <- proplists:get_keys(Files)];
View Code

      根据include_files参数决定配置文件里面是否包含配置子文件(默认开启)

根据replace_macros是否开启决定是否替换macros

然后执行下面的代码

State1 = lists:foldl(fun process_term/2, State, Head ++ Tail),
State1#state{opts = compact(State1#state.opts)}.
View Code

然后对module顾虑无用的参数validate_opts

然后执行下面代码则执行完毕

{MegaSecs, Secs, _} = now(),
    UnixTime = MegaSecs*1000000 + Secs,
    SharedKey = case erlang:get_cookie() of
                    nocookie ->
                        p1_sha:sha(randoms:get_string());
                    Cookie ->
                        p1_sha:sha(jlib:atom_to_binary(Cookie))
                end,
    State1 = set_option({node_start, global}, UnixTime, State),
    State2 = set_option({shared_key, global}, SharedKey, State1),
    set_opts(State2).
View Code

 set_opts把配置文件内容写入数据表local_config中

原文地址:https://www.cnblogs.com/lawen/p/5047511.html