Супервизор Erlang молча не запускается

Я новичок в Erlang, изучаю OTP. Я получил ошибку noproc при попытке поговорить с руководителем во время выполнения. На самом деле, start_link этого супервизора (реализованный мной, а не супервизором:start_link()), похоже, не был выполнен, так как io:fwrite в его первой строке даже не было выведено.

Выяснилось, что проблема заключалась в том, что у одного из дочерних элементов супервизора отсутствовали некоторые gen_server функции обратного вызова (которые не использовались приложением). Компилятор выдал предупреждение об этом и все, ошибок при запуске приложения не было. Я не уверен, что происходит, но разве не должно быть какой-то индикации ошибки?

Если это важно, вот как выглядит дочерняя спецификация самого супервизора:

ElementSup = {sc_element_sup,
                    {sc_element_sup, start_link, []},
                    permanent, 2000, supervisor, [sc_element]},

person Nikita Fuchs    schedule 06.12.2020    source источник
comment
Как вы компилируете?   -  person 7stud    schedule 07.12.2020
comment
С $ erlc -o ebin src/*erl источником является приложение по адресу: github.com/erlware/Erlang-and-OTP-in-Action-Source/blob/master/ , я пропустил последние четыре функции обратного вызова.   -  person Nikita Fuchs    schedule 08.12.2020


Ответы (1)


Сначала я получаю ошибку компилятора:

2> c(my_worker).
my_worker.erl:5: function terminate/2 undefined
error

Затем супервизор сообщает мне, что он не запустился, потому что не смог запустить всех своих дочерних элементов:

3> my_sup:start_link().                  
** exception exit: {shutdown,
                    {failed_to_start_child,my_worker, 
                     {'EXIT',
                      {undef,
                       [{my_worker,start_link,[],[]},
                        {supervisor,do_start_child,2,
                         [{file,"supervisor.erl"},{line,365}]},
                        {supervisor,start_children,3,
                         [{file,"supervisor.erl"},{line,348}]},
                        {supervisor,init_children,2, 
                         [{file,"supervisor.erl"},{line,314}]},
                        {gen_server,init_it,2,
                         [{file,"gen_server.erl"},{line,365}]},
                        {gen_server,init_it,6,
                         [{file,"gen_server.erl"},{line,333}]},
                        {proc_lib,init_p_do_apply,3,
                         [{file,"proc_lib.erl"},{line,247}]}]}}}}

На самом деле, start_link этого супервизора, казалось, не выполнялся, так как io:fwrite в его первой строке даже не выводился.

Функция супервизора start_link() определена в библиотеке одноразовых паролей, поэтому в этой функции не может быть io:fwrite(). Вы можете добавить строку io:fwrite() к определяемой вами функции, которая, в свою очередь, вызывает supervisor:start_link(), например:

start_my_supervisor() ->
    io:format("hello~n"),
    Args = [],
    supervisor:start_link({local, ?MODULE}, ?MODULE, Args).

Приветственное сообщение отлично отображается в моем выводе оболочки erlang.

person 7stud    schedule 07.12.2020
comment
Плохо, я имел в виду не supervisor:start_link, а start_link() в моем супервизоре, который, казалось, не выполнялся, когда в дочернем модуле отсутствовали функции обратного вызова. io:fwrite() зарегистрировался только после того, как я исправил ошибку, поэтому такое впечатление, что он даже не запускался и супервизор даже не запускался, потому что ошибки тоже не было вообще. - person Nikita Fuchs; 08.12.2020