Supervisor 不会在 econnrefused 时重新启动(在 init/1 中抛出)

Supervisor does not restart on econnrefused (thrown in init/1)

我有一个 gen_server 的 init 函数连接到 rabbitmq。当一切都很好时,它工作得很好,但是当连接到 rabbitmq 失败并且我调用 exit 时,该过程不会重新启动。

我想在我调用 exit 后让主管重新启动此过程。

概念上我的 init 函数是这样的:

init(_Args) ->
  process_flag(trap_exit, true),
  case connect() of
    {error, econnrefused} ->
            timer:sleep(1000),
            exit(econnrefused);
    {ok, Connection} ->
            .....
  end,
  {ok, {}}.

这是我的主管:

-module(tasks_manager_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
-define(SERVER, ?MODULE).

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

init([]) ->
    {ok,
     {#{strategy => one_for_one, 
        intensity => 50,
        period => 10},
      [#{id => tasks_manager_serv_id,
         start => {tasks_manager_serv, start_link, []},
         restart => permanent,
         shutdown => brutal_kill,
         type => worker,
         modules => [tasks_manager_serv]}]}}.

我收到的错误如下。你可以看到这个错误没有重新启动,它只是终止:

Starting {global,tasks_da_serv} (<0.479.0>)
Starting {global,tasks_manager_serv} (<0.483.0>)

 =INFO REPORT==== 9-Jun-2017::09:52:46 ===
     application: tasks
     exited: {{shutdown,
                  {failed_to_start_child,tasks_manager_sup_id,
                      {shutdown,
                          {failed_to_start_child,tasks_manager_serv_id,
                              econnrefused}}}},
              {tasks_app,start,[normal,[]]}}
     type: permanent
 {"Kernel pid terminated",application_controller,"{application_start_failure,tasks,{{shutdown,{failed_to_start_child,tasks_manager_sup_id,{shutdown,{failed_to_start_child,tasks_manager_serv_id,econnrefused}}}},{tasks_app,start,[normal,[]]}}}"}
 Kernel pid terminated (application_controller) ({application_start_failure,tasks,{{shutdown,{failed_to_start_child,tasks_manager_sup_id,{shutdown,{failed_to_start_child,tasks_manager_serv_id,econnrefu

我也尝试过将消息投射到 self()(从 init 函数)并在 handle_cast 中连接到 rabbit,但效果不佳。

我还在学习 Erlang/OTP 如果我问的是一些显而易见的问题但我在文档中找不到我的问题的任何答案,请原谅我。

多亏了问题下方的评论,我才得以解决。 基本上问题是进程没有正确启动,因为 exit(econnrefused)init/1 函数中。这就是主管没有重新启动进程的原因 - 它不会重新启动未能初始化的进程。

现在我正在向 self() 发送消息,然后在 hangle_info/2 中接收它,如下所示:

init(_Args) ->
    process_flag(trap_exit, true),
    io:format("Starting ~p (~p)~n", [{global, ?MODULE}, self()]),
    self() ! connect,
    {ok, {}}.

handle_info(connect, State) ->
    {ok, Connection, Channel} = establish_rabbit_connection(),
    {noreply, #state{connection = Connection, channel = Channel}};