【问题标题】:How to determine if a worker in a supervision tree is starting for the very first time or has been restarted如何确定监督树中的工作人员是首次启动还是已重新启动
【发布时间】:2012-12-17 17:19:51
【问题描述】:

我有一个简单的主管配置:

-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 函数,还是工作进程在过去某个时候崩溃并且现在正在重新启动?

【问题讨论】:

  • 通常,您可以编写 my_worker 使其始终认为它是第一次启动并基于此重新创建其假设。这将使了解 my_worker 的当前启动状态变得不那么重要。如果您想对此进行计数,请在 ETS 表中的流程和监督树之外进行计数,或者通过您在重新启动时 ping 的计数过程进行。
  • 我认为这只有在您使用某种副作用策略时才有可能 - ping(并增加)计数过程,增加 ets 表中的记录(如对您的 OP 的评论中所述)等等。所有这些都让我很好奇你为什么关心?通过知道某个工作器已重新启动,您想解决什么问题?

标签: erlang erlang-otp erlang-supervisor


【解决方案1】:
  1. 用于确定这是否是主管第一次调用start_link 函数。 您可以使用childId参数并从外部传递childId,具体方法请参见erlang supervisor

    start_child(ChildId, Mod, Args) -> {ok, _} = 主管:start_child(?SERVER, {ChildId, {Mod, start_link, Args}, 瞬态,?MAX_WAIT,工人,[Mod]}), 好的。

  2. 用于确定worker 已重新启动。请阅读monitor and link的文件。当崩溃发生时,你的进程会收到消息。如果你看过supervisor的源码,你会发现supervisor实际上是使用link and monitor来解决crash监控任务的。

3.

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

【讨论】:

  • 1. start_child(ChildId, Mod, Args) -> {ok, _} = supervisor:start_child(?SERVER, {ChildId, {Mod, start_link, Args}, transient, ?MAX_WAIT, worker, [Mod]}),好的。每次重新启动进程(包括第一次启动)时,Args 都会传递给 start_link 回调函数,所以我不明白这对我有什么帮助。论点总是相同的。 2.我不想明确地监控我的工作进程(这就是主管的作用)我只是主管告诉我是否我以前崩溃过。
  • 我已经为您的碰撞护理过程添加了第 3 项
  • 再一次,我不想自己监控进程,我不想trap_exits和link。我希望主管为我完成所有工作,并为我提供有关正在发生的事情的必要信息。
  • 也许 SASL 就是您想要的。它在 error_logger 事件管理器中记录崩溃信息,您可以从那里获取崩溃事件。
猜你喜欢
  • 1970-01-01
  • 2017-09-10
  • 2017-01-09
  • 2016-05-27
  • 2018-11-12
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
相关资源
最近更新 更多