Erlang как настроить приложение дерева супервизора, которое является автономным

Я не уверен, смогу ли я правильно сформулировать свой вопрос, но я постараюсь изо всех сил.

Мне кажется неудобным то, как вам нужно настроить дерево супервизоров (sup, sup-tress и другие более сложные деревья).

Возьмем, к примеру, следующее (я уже сделал эти примеры и расширил их): http://learnyousomeerlang.com/supervisors

Мне не нравится идея запуска моего приложения (деревья супервизоров), а затем необходимость отправлять команды erl в оболочке, чтобы приложение вело себя так, как я тоже. Возьмите пример нижней оболочки с сайта:

1> supervisor:start_child(band_supervisor, [djembe, good]).
Musician Janet Tennelli, playing the djembe entered the room
{ok,<0.690.0>}
2> supervisor:start_child(band_supervisor, [djembe, good]).
{error,{already_started,<0.690.0>}}
3> supervisor:start_child(band_supervisor, [drum, good]).
Musician Arnold Ramon, playing the drum entered the room
{ok,<0.696.0>}
3> supervisor:start_child(band_supervisor, [guitar, good]).
Musician Wanda Perlstein, playing the guitar entered the room
{ok,<0.698.0>}
4> supervisor:terminate_child(band_supervisor, djembe).
{error,simple_one_for_one}
5> musicians:stop(drum).
Arnold Ramon left the room (drum)
ok

Для меня это странно, мне пришлось бы запускать своего супервизора (или что-то еще), а затем вводить другие команды через оболочку, чтобы получить то, что я хочу.

В качестве реального примера скажем, например, что у меня есть диспетчер прослушивания, и в этом диспетчере я говорю, что хочу всегда иметь 100 сотрудников прослушивания. Их задача - прослушивать сокет, созданный Listen Supervisor. Учитывая учебник (и другие онлайн-версии), мне пришлось бы вводить оболочку 100 раз, чтобы запустить всех дочерних элементов.

Итак, я предполагаю, что мой вопрос следующий ...

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

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

Спасибо за ваше время.


person Mike5050    schedule 30.08.2017    source источник


Ответы (1)


У вас есть несколько вариантов.

Вы можете определить некоторые переменные в env файла .app или в файл sys.config и поместите их в init/1 супервизора и верните достаточное количество дочерних спецификаций.

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

person Pouriya    schedule 31.08.2017
comment
Итак, для каждого listen_worker мне нужно иметь дочернюю спецификацию внутри listen_sup? Я думал, что мне не нужно этого делать, просто добавить ребенка с командой супервизора? - person Mike5050; 31.08.2017
comment
да, вам нужно, также когда вы запускаете нового ребенка, вы добавляете новый childspec в childspecs супервизора. - person Pouriya; 31.08.2017
comment
Так что мне просто нужен способ сгенерировать 100 дочерних спецификаций ... Есть какой-нибудь код, который делает это автоматически? (их все те же рабочие) - person Mike5050; 31.08.2017
comment
Это выглядит просто: [#{id=>Int, start=>{... } || Int <- lists:seq(1, 100)] создает 100 дочерних спецификаций! - person Pouriya; 31.08.2017