gen_server и ошибки времени выполнения - PullRequest
2 голосов
/ 08 декабря 2010

У меня ошибка во время выполнения в части инициализации gen_server.- Init begin by process_flag (trap_exit, true) - gen_server является частью дерева контроля, я пытаюсь напечатать причину в модуле завершения, но, похоже, он выходит из другого места- почему термин не называется?Приложение останавливается с отключением в качестве причины.- Как и где отловить ошибку во время выполнения?

1 Ответ

4 голосов
/ 08 декабря 2010

В этой ситуации обычно вызывается обратный вызов terminate, а именно потому, что вы перехватили выходы.

Единственное место, где это не так, это если происходит сбой в функции инициализации. В этом случае ответственность лежит на наблюдателе, который в результате обычно прекращает свою деятельность. Затем эта ошибка ползет по дереву супервизора, пока не завершится завершением всего приложения.

Обычно супервизор регистрирует отчет супервизора с контекстом, установленным на start_error. Это ваш намек на то, что у части дерева контроля есть проблемы, с которыми вы должны справиться. Вы должны проверить это, поскольку у вас может быть неверное предположение о том, где произошла ошибка.

ИЗД. ЗДЕСЬ

Ваша проблема в том, что вы вообще не знаете о SASL. Изучите это. Вот пример того, как его использовать.

Поднятый код из вашего примера:

Во-первых, бахлонга должен был сказать Эрлангу, что у нас есть сервер gen_server.

-module(foo).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
     terminate/2, code_change/3]).

Мы взломали запись #state {}, чтобы ее можно было использовать с вашим кодом

-record(state, { name, port, socket_listen }).

Basic start_linkage ...

start_link() ->
    gen_server:start_link({local, foo}, ?MODULE, [], []).

Ваша функция инициализации, включая проблему появления.

init([]) ->
    Port = 3252,
    Name = "foo",

Выше мы взломали немного ради упрощения ...

    process_flag(trap_exit, true),
    erlang:error(blabla),
    Opts = [binary, {reuseaddr, true},
        {backlog,5}, {packet, 0}, {active, false}, {nodelay, true}],
    case gen_tcp:listen(Port,Opts) of
    {ok,Socket_Listen} ->
        logger:fmsg("--> [~s,init] Socket_Listen crée = ~p",
            [Name,Socket_Listen]),
        {ok,handle_accept(#state{socket_listen=Socket_Listen})};
    {error, Reason} ->
        logger:fmsg("--> [~s,init] Erreur, Raison =~p",
            [Name,Reason]), {stop, Reason}
    end.

Хаки для отсутствующих функций ....

handle_accept(_) ->
    #state{}.

Остальное - только основы ... поэтому я их опускаю.

Теперь для foo_sup супервайзер для foo:

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

Базовая стартовая ссылка ...

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

Basic ChildSpec. Получи ребенка и беги ...

init([]) ->
    FooCh = {foo, {foo, start_link, []},
         permanent, 2000, worker, [foo]},
    {ok, {{one_for_all,0,1}, [FooCh]}}.

Загрузка Erlang с включенным SASL:

 jlouis@illithid:~$ erl -boot start_sasl
 Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

 =PROGRESS REPORT==== 9-Dec-2010::01:01:51 ===
 [..]
 Eshell V5.8.3  (abort with ^G)

Давайте попробуем порождать супервизора ...

 1> foo_sup:start_link().

И мы получаем это:

=CRASH REPORT==== 9-Dec-2010::01:05:48 ===
  crasher:
    initial call: foo:init/1
    pid: <0.58.0>
    registered_name: []
    exception exit: {blabla,[{foo,init,1},
                             {gen_server,init_it,6},
                             {proc_lib,init_p_do_apply,3}]}

Выше мы видим, что у нас произошел сбой в foo:init/1 из-за исключения blabla.

      in function  gen_server:init_it/6
    ancestors: [foo_sup,<0.45.0>]
    messages: []
    links: [<0.57.0>]
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 233
    stack_size: 24
    reductions: 108
  neighbours:

И теперь руководитель получает возможность сообщить о проблеме!

=SUPERVISOR REPORT==== 9-Dec-2010::01:05:48 ===
     Supervisor: {local,foo_sup}
     Context:    start_error

Контекст точно , как я сказал, это будет ...

     Reason:     {blabla,[{foo,init,1},
                          {gen_server,init_it,6},
                          {proc_lib,init_p_do_apply,3}]}

И с ожидаемой причиной.

     Offender:   [{pid,undefined},
                  {name,foo},
                  {mfargs,{foo,start_link,[]}},
                  {restart_type,permanent},
                  {shutdown,2000},
                  {child_type,worker}]
...