Как может супервизор, достигший_max_restart_intensity, удалить только нарушившего ребенка?

У меня есть one_for_one руководитель, который занимается похожими и полностью независимыми детьми.

Когда есть проблема с одним дочерним элементом, который постоянно вылетает и запускается:

=SUPERVISOR REPORT==== 30-Mar-2011::13:10:42 ===
     Supervisor: {local,gateway_sup}
     Context:    shutdown
     Reason:     reached_max_restart_intensity
     Offender:   [{pid,<0.76.0>}, ...

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

Как я могу построить дерево супервизоров из стандартных супервизоров Erlang, которое останавливается только для перезапуска одного нарушившего ребенка и оставляет остальных в покое?

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

Есть ли другие способы справиться с этим?


person Peer Stritzinger    schedule 30.03.2011    source источник
comment
Дополнительный супервизор просто отодвинет проблему еще дальше. Он все равно выйдет из строя, а затем выйдет из строя супервизор верхнего уровня. В этом случае просто увеличьте максимальное количество перезапусков и максимальное время ...   -  person Adam Lindberg    schedule 30.03.2011
comment
@ Адам: Мне нужно прекратить перезапуск ребенка, потому что это, кажется, мешает мне разговаривать с руководителем. Поэтому я действительно хочу, чтобы он перестал перезапускать обидного ребенка, но не завершал работу остальных. Я надеялся, что этого можно будет достичь без написания собственного руководителя.   -  person Peer Stritzinger    schedule 30.03.2011
comment
Поправьте меня, если я ошибаюсь, но я резюмирую ваш сценарий так: у вас есть супервизор с полностью независимыми дочерними элементами, где дети могут либо тайм-аут при запуске, либо сбой во время выполнения, и вы хотите перезапустить каждый дочерний элемент самостоятельно и прекратить перезапуск некорректного поведения ребенок, не затрагивая других детей?   -  person Adam Lindberg    schedule 30.03.2011
comment
Похоже, ты ошибаешься. Решение Адама аккуратно решает проблему, но кажется, что вам нужно взглянуть на то, почему вы падаете, а не на то, чтобы ждать ручного вмешательства. Если ваш супервизор заблокирован, потому что он занят попыткой перезапустить что-то, что мгновенно дает сбой, вы ошибаетесь. (Да, есть такая вещь, как сбой;) Я бы посоветовал пересмотреть вашу стратегию восстановления, т.е. как вы перезапускаетесь после сбоя и какие ошибочные данные могут замкнуть его в замкнутый цикл.   -  person Mazen Harake    schedule 31.03.2011
comment
@Mazen: вы правы: я ошибаюсь и собираюсь это исправить. Но я использовал возможность, чтобы сделать весь супервизор более устойчивым к ошибочным сбоям. Проблема в том, что, хотя я могу улучшить общий случай, код, который я начинаю с этого, имеет довольно сложный запуск, и очень важно, чтобы другие дочерние элементы продолжали работать, даже если один из них неожиданно будет вести себя очень неприятно (завершение дочерних элементов без причины приведет к значительным денежным потеря для клиента здесь, может даже быть повреждено оборудование, когда это произойдет)   -  person Peer Stritzinger    schedule 31.03.2011


Ответы (1)


Я думаю, что лучшим решением было бы иметь двухуровневый надзор.

Один супервизор, который запускает пару супервизор + процесс для каждого gen_server, который вы хотите запустить. Этот супервизор настроен с one_for_one стратегией и temporary дочерними элементами.

Каждый супервизор, работающий под этим супервизором, должен правильно сконфигурировать значения MaxR и MaxT, что вызовет сбой этого супервизора, как только дочерний элемент будет неправильно себя вести.

Когда супервизор нижнего уровня выходит из строя, супервизору верхнего уровня «все равно».

Супервизор потребляет 233 байта при запуске с одним потомком (общий размер кучи), поэтому потребление памяти не должно быть проблемой.

Дерево надзора должно выглядеть так:

supervisor_top
    |
    |
    +------------------------+-----    ...
    |                        |
 supervisor_1               supervisor_2
 restart temporary          restart temporary
    |                         |
  gen_server_1              gen_server_2
  restart transient         restart transient
person Adam Lindberg    schedule 30.03.2011
comment
Я добавил диаграмму к вашему ответу, насколько я понимаю. Вы это имели в виду? - person Peer Stritzinger; 30.03.2011
comment
Спасибо! Кстати, эта настройка также позволяет избежать проблемы заблокированного супервизора через цикл перезапуска (stackoverflow.com/questions/5485402/), поскольку supervisor_top изолирован возможными циклами перезапуска, которые не запускают ограничение скорости промежуточными супервизорами. - person Peer Stritzinger; 30.03.2011