Супервайзеры с откатом - PullRequest
       17

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

6 голосов
/ 24 сентября 2010

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

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

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

Ответы [ 3 ]

5 голосов
/ 24 сентября 2010

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

5 голосов
/ 24 сентября 2010

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

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

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

1 голос
/ 27 декабря 2017

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

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

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

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

handle_info({die, Reason}, State) ->
    {stop, Reason, State};
...