gpt4 book ai didi

erlang - 在事先不知道 N 的情况下,在主管中声明 N 名 worker 的最佳方法

转载 作者:行者123 更新时间:2023-12-02 22:43:14 26 4
gpt4 key购买 nike

我正在开发一个有 1 名主管和几名 worker 的应用程序。这些工作人员中的每一个都将打开一个 tcp 套接字,执行一个监听,然后接受连接,在每个客户端到达时为每个客户端生成一个进程(我不介意监督这些)。

我想在应用程序配置中配置监听地址,这样我就可以根据需要监听任意数量的地址(至少需要 1 个地址,但可以指定任意数量)。每个地址都是一个 ip(或主机名)和一个端口地址。到目前为止,没有新内容。

我的问题是关于如何申报、启动和监督数量未知的 worker 。我的解决方案是在主管代码中动态生成(在运行时)init/1 函数的结果,如下所示:

-define(
CHILD(Name, Args),
{Name, {
?MODULE, start_listen, Args
}, permanent, 5000, worker, [?MODULE]
}
).

init([]) ->
{ok, Addresses} = application:get_env(listen),
Children = lists:map(
fun(Address) ->
{X1,X2,X3} = os:timestamp(),
ChildName = string:join([
"Listener-",
integer_to_list(X1),
integer_to_list(X2),
integer_to_list(X3)
], ""),
?CHILD(ChildName, [Address])
end,
Addresses
),
{ok, { {one_for_one, 5, 10}, Children }}.

这允许我为每个工作人员动态生成一个名称,并生成工作人员定义。所以:

  1. 这个解决方案可以接受吗?在我看来,它并不那么优雅。是否有针对此类用例的标准解决方案(或最佳实践等)?

  2. 我知道“simple_one_for_one”策略,它允许动态地将 worker 添加到主管。但是它也可以用来动态生成 worker 的名字吗?使用“simple_one_for_one”而不是我自己使用“one_for_one”的解决方案(以任何方式)更好吗? (同样,针对这种特殊情况)。

提前致谢,抱歉发了这么长的帖子! :)

最佳答案

使用 simple_one_for_one :

在你的 worker 的 init 函数中,你可以将它们注册到一个表中,将名称与它们的 PID 相关联,这样你就可以从名称中获取 pid。

您可以使用 global 模块(或 gproc !)将名称与 pid 相关联。当进程死掉时,globalgproc 会自动删除该名称,因此当 supervisor 重新启动子进程时,该名称可用。

您将在 supervisor:start_child/2 的参数列表(第二个参数)中传递名称

使用 simple_one_for_one 将允许您在主管初始化后动态添加更多监听器。

如果您需要此功能,simple_one_for_one 是不错的解决方案。

如果您坚持在 sup 的 init 函数中使用动态内容的解决方案,您可以像这样清理代码,它可能会或可能不会看起来更优雅:

-define(
CHILD(Name, Args),
{Name, {
?MODULE, start_listen, Args
}, permanent, 5000, worker, [?MODULE]
}
).

generate_names(Adresses) -> generate_names(Adresses, 1, []).

generate_names([], _, Acc) -> Acc;
generate_names([Addr|Addresses], ID, Acc) -> generate_names(Addresses, ID+1, [{id_name(ID), Addr}|Acc]).

id_name(ID) -> "listener-" ++ integer_to_list(ID).

init([]]) ->
{ok, Addresses} = application:get_env(listen),
Children = [?CHILD(Name, Address) || {Name, Address} <- generate_names(Addresses)],
{ok, { {one_for_one, 5, 10}, Children }}.

或者使用 lists:foldl 代替所有这些小函数来保持代码简短。

但无论如何我会在 init 的 Args 列表中传递地址,而不是在 init 中调用 get_env 以保持它的纯净。

关于erlang - 在事先不知道 N 的情况下,在主管中声明 N 名 worker 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10455035/

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