Iva*_*rov 19 erlang configuration
我需要通过我的应用程序分发某种静态配置.这样做的最佳做法是什么?
我看到三个选择:
application:get_env
只要模块需要获取配置值,就直接调用.
application:get_env
在启动期间将配置(从中检索)传递给应用程序模块.
Gre*_*ill 12
另一种方法是将配置数据转换为Erlang源模块,通过导出使配置数据可用.然后,您只需加载新版本的配置模块,即可在运行的系统中随时更改配置.
Dav*_*don 10
对于我自己项目中的静态配置,我喜欢选项(1).我将向您展示我访问在名为max_widgets
的应用程序中调用的配置参数的步骤factory
.
首先,我们将创建一个名为的模块factory_env
,其中包含以下内容:
-define(APPLICATION, factory).
get_env(Key, Default) ->
case application:get_env(?APPLICATION, Key) of
{ok, Value} -> Value;
undefined -> Default
end.
set_env(Key, Value) ->
application:set_env(?APPLICATION, Key, Value).
Run Code Online (Sandbox Code Playgroud)
接下来,在需要阅读的模块中,max_widgets
我们将定义如下的宏:
-define(MAX_WIDGETS, factory_env:get_env(max_widgets, 1000)).
Run Code Online (Sandbox Code Playgroud)
这种方法有一些好处:
application:set_env/3
和application:get_env/2
,我们实际上并不需要启动factory
以应用有我们的测试通过.max_widgets
获取默认值,因此即使未定义参数,我们的代码仍然可以工作.max_widgets
.最后,当我们准备好部署时,我们将把sys.config文件放在我们的priv
目录中并-config priv/sys.config
在启动期间加载它.这允许我们根据需要在每个节点上更改配置参数.这将配置与代码完全分开 - 例如,我们不需要再次提交以更改max_widgets
为500.
您可以使用进程(gen_server可能?)将配置参数存储在其状态中.它应该公开一个get/set接口.如果尚未显式设置值,则应检索默认值.
-export([get/1, set/2]).
...
get(Param) ->
gen_server:call(?MODULE, {get, Param}).
...
handle_call({get, Param}, _From, State) ->
case lookup(Param, State#state.params) of
undefined ->
application:get_env(...);
Value ->
{ok, Value}
end.
...
Run Code Online (Sandbox Code Playgroud)
然后,您可以在测试中轻松模拟此模块.在运行时使用一些新配置更新过程也很容易.
您可以使用模式匹配和元组将不同的配置参数关联到不同的模块:
set({ModuleName, ParamName}, Value) ->
...
get({ModuleName, ParamName}) ->
...
Run Code Online (Sandbox Code Playgroud)
将该过程置于监督树下,因此它将在所有其他需要配置的过程之前启动.
哦,我很高兴到目前为止没有人建议参数化模块 :)
归档时间: |
|
查看次数: |
7256 次 |
最近记录: |