Супервайзеры с отсрочкой

У меня есть супервизор с двумя рабочими процессами: TCP-клиент, который обрабатывает подключение к удаленному серверу, и FSM, который обрабатывает протокол подключения.

Обработка ошибок TCP в дочернем процессе значительно усложняет код. Так что я бы предпочел "пусть рухнет", но тут другая проблема: когда сервер недоступен, быстро будет достигнуто максимальное количество рестартов и супервизор рухнет вместе со всем моим приложением, что весьма нежелательно для Это дело.

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


person Alexey Romanov    schedule 24.09.2010    source источник
comment
Я бы сказал, что стратегия в вашем случае кажется неправильной. Я имею в виду, что если вы хотите, чтобы он рухнул, но в то же время немедленно перезапустил его, то нет причин допускать его крах, потому что вы просто используете супервизор в качестве механизма повторной попытки. Это просто неправильно имхо. Вы должны дать ему сбой, поместить код в последовательность запуска, если вы ждете ресурсов, и НЕ повторять попытку с ошибкой. Я видел это раньше, и обычно это ошибка дизайна, а не ограничение супервизора. Пища для размышлений.   -  person Mazen Harake    schedule 26.09.2010


Ответы (3)


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

person Dustin    schedule 24.09.2010
comment
Ссылка снова 404. - person Brian Antonelli; 23.09.2013
comment
Спасибо, @BrianAntonelli - проблема с указанием на живой код заключается в том, что люди перемещают вещи. - person Dustin; 29.09.2013
comment
ссылка @Dustin на конкретный коммит; таким образом, ссылка будет действительна до тех пор, пока история Git не будет перезаписана. alxndr.github.io/blog/2016/05/06/ - person alxndr; 02.01.2018

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

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

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

person cthulahoops    schedule 24.09.2010

Итак, сначала вы хотите поймать досрочное прекращение дочернего процесса, используя process_flag(trap_exit, true) в вашем файле init.

Затем вам нужно решить, на какое время вы хотите отложить перезапуск, например, на 10 секунд, сделайте это в

handle_info({'EXIT', _Pid, Reason}, State) ->
    erlang:send_after(10000, self(), {die, Reason}),  
    {noreply, State};

Наконец, пусть процесс умрет с

handle_info({die, Reason}, State) ->
    {stop, Reason, State};
person Roman Rabinovich    schedule 27.12.2017
comment
Здравствуйте Роман, и добро пожаловать на сайт. Нам нравится, чтобы вопросы и ответы были здесь очень точными, поэтому я пошел дальше и немного сократил ваш ответ. Не стесняйтесь редактировать его снова, если вас не устраивают мои изменения. - person MackM; 27.12.2017