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