Erlang 如何确定监督树中的工作人员是第一次启动还是已重新启动
我有一个简单的管理器配置:Erlang 如何确定监督树中的工作人员是第一次启动还是已重新启动,erlang,otp,erlang-supervisor,Erlang,Otp,Erlang Supervisor,我有一个简单的管理器配置: -module(my_supervisor). -behaviour(supervisor). -export([start_link/0, init/1]). init(_Args) -> {ok, { {one_for_one, 5, 10}, [ {my_worker, {my_worker, start_link, []}, permanent, 5000, worker, [my_worker]}
-module(my_supervisor).
-behaviour(supervisor).
-export([start_link/0, init/1]).
init(_Args) ->
{ok, { {one_for_one, 5, 10},
[
{my_worker, {my_worker, start_link, []}, permanent, 5000, worker, [my_worker]}
]
}
}.
即使是简单的工人:
-module(my_worker).
-export([start_link/0]).
start_link() ->
%??? is this the first time the supervisor is starting me or have I crashed and been restarted???
那么,是否有可能确定这是主管第一次调用start_link函数,还是工作进程在过去某个时候崩溃,现在正在重新启动
start\u link
函数。
您可以使用childId
参数,从外部传递childId
,如下所示,详情请参见doc about
开始\u子项(ChildId、Mod、Args)->
{ok,{}=主管:启动子服务器(?服务器,
{ChildId,{Mod,start_link,Args},
瞬态,?最大等待时间,工人,[Mod]}),
嗯主管
的源代码,您会发现主管实际上使用了链接和监视器
来解决崩溃
监视器任务1.start_child(ChildId,Mod,Args)->{ok,{U}=主管:start_child(?SERVER,{ChildId,{Mod,start_link,Args},transient,?MAX_WAIT,worker,[Mod]}),ok。每次进程重新启动(包括第一次启动)时,Args都会传递给start_link回调函数,因此我不知道这对我有什么帮助。争论总是一样的。2.我不想明确地监视我的工作进程(这是主管的职责),我只想知道主管在我以前崩溃时告诉我什么。我再次为您的崩溃关注进程添加了第3项,我不想自己监视进程,我不想陷阱退出和链接。我想要的是主管为我做所有的工作,并为我提供关于正在发生的事情的必要信息。也许SASL就是你想要的。它在error_logger event manager中记录崩溃信息,您可以从中获取崩溃事件。通常,您可以编写my_worker,使其始终认为它是第一次启动的,并基于此重新创建其假设。这将使了解我的工作人员的当前启动状态变得不那么重要。如果你想计数,可以在ETS表中的进程和监督树之外进行,或者在每次重新启动时通过ping的计数进程进行。我认为这只有在使用某种副作用策略的情况下才有可能——ping(并递增)计数进程,递增ETS表中的记录(如OP评论中所述),所有这些都让我好奇你为什么关心?通过知道工作进程已重新启动,您试图解决什么问题?
init([]) ->
process_flag(trap_exit, true),
...
terminate(_Reason, _State) ->
% may be crash here by check reason above.
ok.
handle_info({'EXIT',Self,Reason},State#state{self=Self)->
error_logger:info_report([crash_now]),
{stop,Reason,State};
[1]: http://www.erlang.org/doc/man/supervisor.html