【问题标题】:Correct way to shut down when trapping exits?陷阱出口时关闭的正确方法?
【发布时间】:2018-09-14 11:19:57
【问题描述】:

我有一个 gen_server,我用它来捕获出口

%% worker.erl
% ...
init(args) ->
  process_flag(trap_exit, true)
  % ...

handle_info({'EXIT', SpecialPid, Reason}, SpecialPid) ->
  % terminate
  exit(normal);
handle_info({'EXIT', _NormalPid, _Reason}, SpecialPid) ->
  % ignore     
  {noreply, SpecialPid}.

我希望能够关闭此gen_server 的监督树:

%% sup_sup.erl
% ...
  supervisor:terminate_child(self(), worker_sup),
% ...

当我运行时,我可以终止工人。但是,我收到 OTP 错误,好像进程终止是意外的。我还尝试了exit(normal) 并返回{stop, normal, State}{stop, shutdown, State},它们都产生相同的效果。

在关闭期间模拟 OTP 行为的正确方法是什么,同时在其他情况下仍捕获退出?

【问题讨论】:

  • handle_info返回{stop, normal, state}怎么样?
  • 对不起,是的,我确实尝试过。我一直在精神上将stophalt 转换,但我保证我在实际代码中用stop 尝试过:)
  • 您的代码似乎将 erlang 的东西(如函数子句等)与 elixir 的东西(如小写变量和:noreply)混合在一起。

标签: erlang


【解决方案1】:

您只需从您的handle_info/2 返回{stop, normal, State)。根据您用于此流程的子规范,您可能仍会从主管那里收到信息/错误消息。

如果您希望您的进程在完成其工作后停止并且不重新启动,您应该在子规范中使用restart => transient。这样,如果进程因任何其他非正常原因退出,它将重新启动。但是使用{stop, normal, State} 时不应该收到任何消息。

【讨论】:

    猜你喜欢
    • 2020-05-11
    • 2010-09-14
    • 2012-02-19
    • 2010-11-16
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    相关资源
    最近更新 更多