Добавлены супервизоры для gen_server, немедленное отключение?

ИЗМЕНИТЬ: ниже.

Почему мой контролируемый gen_server так быстро отключается?

Я дам эти организационные имена, чтобы сделать более понятной цепочку команд, которую я хочу использовать в своем приложении: сначала я начну с «монтажного_линейного_работника», а позже я добавлю «специалиста по маркетингу» в свое дерево наблюдения...

ceo_supervisor.erl

-module(ceo_supervisor).
-behaviour(supervisor).

-export([start_link/1]).
-export([init/1]).

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

init([Args]) ->
     RestartStrategy = {one_for_one, 10, 60},
     ChildSpec= {assembly_line_worker_supervisor,
          {assembly_line_worker_supervisor, start_link, [Args]},
          permanent, infinity, supervisor, [assembly_line_worker_supervisor]},
     {ok, {RestartStrategy, [ChildSpec]}}.    

assembly_line_worker_supervisor.erl

-module(assembly_line_worker_supervisor).
-behaviour(supervisor).

-export([start_link/1]).
-export([init/1]). %% Internal

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

init([Args]) ->
    RestartStrategy = {one_for_one, 10, 60},
    ChildSpec = {assembly_line_worker, {assembly_line_worker, start_link, [Args]}, permanent,     
        infinity, worker, [assembly_line_worker]},
    {ok, {RestartStrategy, [ChildSpec]}}.

assembly_line_worker.erl

-module(assembly_line_worker).
...

init([State]) ->
   process_flag(trap_exit, true),
   {ok, State}.

start_link(State) ->
    gen_server:start_link({global, ?MODULE}, ?MODULE, [State], []).

handle_cast(...,State} ->
    io:format("We're getting this message.~n",[]),
    {noreply, State};
...

Происходит то, что работник сборочной линии выполняет небольшую часть работы, например получает пару сообщений, которые отправляются сразу после вызова команды ceo_supervisor:start_link(#innovative_ideas{}), а затем завершает работу. Есть идеи, почему? Я знаю, что gen_server получает несколько сообщений, потому что он io:format отправляет их на консоль.

Спасибо!


EDIT: я размещаю это в Windows через erlsrv.exe, и я обнаружил, что когда я запускаю свою программу с помощью такой функции:

start() ->
    ceo_supervisor:start_link(#innovative_ideas{}),
    assembly_line_worker:ask_for_more_pay(), %% Prints out "I want more $$$" as expected,
    ok.

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

Поэтому я думаю, что лучше было бы задать вопрос, как я могу разрешить своим супервизорам продолжать работу после прохождения всех начальных настроек? Есть ли вариант, кроме как обернуть все это в приложение? (что не так уж и плохо...)

Спасибо за наводящие вопросы! Так я больше узнал о супервайзерах.

Бэтмен


person batman    schedule 10.10.2012    source источник
comment
Можете ли вы предоставить больше вашего файла Assembly_line_worker.erl? Если этот модуль выйдет из строя более 10 раз за 60 секунд, он больше не будет перезапущен. Я предполагаю, что что-то заставляет его превышать максимальный предел перезапуска, но мне нужно увидеть больше кода.   -  person Jr0    schedule 11.10.2012
comment
Это пара сотен строк, но я знаю, что могу нормально запустить его без супервизоров, и в этом отношении он не вылетает / не выдает исключений. Что бы это помогло увидеть?   -  person batman    schedule 11.10.2012
comment
Не могли бы вы привести пример того, как вы вызываете функции при запуске супервайзеров? Мне интересно, совпадают ли все списки в ваших дочерних спецификациях и функциях инициализации. К сожалению, в документации "Args" означает как реальный необходимый список аргументов, так и только один фрагмент данных аргументов.   -  person rvirding    schedule 11.10.2012
comment
Добавлено больше информации. Да, я никогда не ценил это в документах, я думаю, что это следует изменить на ArgsList.   -  person batman    schedule 12.10.2012


Ответы (2)


Чтобы получить больше информации о том, что происходит, запустите sasl перед запуском супервизора: application:start(sasl).

Другим способом отладки этого является запуск рабочего процесса из вашей оболочки erlang, который отправляет последовательность сообщений, которые привели к сбою сервера. Кстати: вы уверены, что вам нужно 2 уровня супервайзеров?

person Andreas Hasselberg    schedule 11.10.2012
comment
В конце концов, когда я добавлю Marketing_specialist_sup, я думаю, что мне нужно, чтобы оба этих супервайзера контролировались чем-то на высшем уровне? Кроме того, я на самом деле не уверен, что мой сервер вышел из строя, потому что я могу запустить его без супервизоров. - person batman; 11.10.2012

Некоторые немедленные комментарии:

В ceo_supervisor:init/1 ваша дочерняя спецификация супервизора должна объявлять transient вместо permanent.

Запустите erl -boot start_sasl, чтобы у вас был журнал ошибок, когда что-то пойдет не так, и вы можете получить отчет о сбое.

Если вы запустите это в оболочке и допустите какую-либо ошибку, ваше дерево будет принудительно уничтожено. Это связано с тем, что вы связались с оболочкой, и оболочка падает при ошибках. Итак, вы тащите свое дерево вниз. Попробуйте что-то вроде:

 Pid = spawn(fun() -> my_app:start() end).

так он у тебя раскололся. Вы можете закрыть приложение, отправив выходное сообщение на Pid.

person I GIVE CRAP ANSWERS    schedule 13.10.2012