gpt4 book ai didi

erlang - 应用程序启动时将一些参数传递给主管 init 函数

转载 作者:行者123 更新时间:2023-12-02 21:21:47 25 4
gpt4 key购买 nike

我想将一些参数传递给 supervisor:init/1 函数,并且希望应用程序的界面如下:

redis_pool:start() % start all instances
redis_pool:start(Names) % start only given instances

这是应用程序:

-module(redis_pool).
-behaviour(application).

...

start() -> % start without params
application:ensure_started(?APP_NAME, transient).

start(Names) -> % start with some params
% I want to pass Names to supervisor init function
% in order to do that I have to bypass application:ensure_started
% which is not GOOD :(
application:load(?APP_NAME),
case start(normal, [Names]) of
{ok, _Pid} -> ok;
{error, {already_started, _Pid}} -> ok
end.

start(_StartType, StartArgs) ->
redis_pool_sup:start_link(StartArgs).

这是主管:

init([]) ->
{ok, Config} = get_config(),
Names = proplists:get_keys(Config),
init([Names]);
init([Names]) ->
{ok, Config} = get_config(),
PoolSpecs = lists:map(fun(Name) ->
PoolName = pool_utils:name_for(Name),
{[Host, Port, Db], PoolSize} = proplists:get_value(Name, Config),
PoolArgs = [{name, {local, PoolName}},
{worker_module, eredis},
{size, PoolSize},
{max_overflow, 0}],
poolboy:child_spec(PoolName, PoolArgs, [Host, Port, Db])
end, Names),
{ok, {{one_for_one, 10000, 1}, PoolSpecs}}.

正如您所看到的,当前的实现很丑陋并且可能存在错误。问题是我如何传递一些参数并启动应用程序和主管(使用给予 start/1 的参数)?

一种选择是启动应用程序并分两个单独的阶段运行 Redis 池。

redis_pool:start(),
redis_pool:run([] | Names).

但是,如果我想在应用程序启动时运行主 pipe 级(redis 池)怎么办?

谢谢。

最佳答案

应用程序回调Module:start/2不是用于启动应用程序的API。当应用程序由 application:start/1,2 启动时调用它。这意味着重载它来提供不同的参数可能是错误的做法。

特别是,如果有人将您的应用程序添加为他们的依赖项(在 foo.app 文件中),application:start 将被直接调用。此时,他们无法控制参数,因为它们来自您的 .app 文件,位于 {mod, {Mod, Args}} 术语。

一些可能的解决方案:

应用程序配置文件

要求参数位于应用程序配置文件中;您可以使用 application:get_env/2,3 检索它们。

不要启动主管

这意味着以下两件事之一:成为库应用程序(从 .app 文件中删除 {mod, Mod} 术语)——您不需要应用程序行为;或者启动一个什么也不做的虚拟主管。

然后,当有人想要使用您的库时,他们可以调用 API 来创建池监督程序,并将其移植到他们的监督树中。这就是 poolboypoolboy:child_spec 所做的事情。

或者,您的应用程序级主管可以是普通主管,默认情况下没有子级,并且您可以通过 supervisor:start_child 提供 API 来启动其子级。这(或多或少)就是cowboy 所做的。

关于erlang - 应用程序启动时将一些参数传递给主管 init 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27149552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com