Проверка существующего дочернего элемента в супервизоре OTP simple_on_for_one

Я пишу счетчик слов map/reduce, чтобы выучить OTP. Я создал супервизор simple_one_for_one, который может запускать редукторы. Для каждого ключа я хотел бы проверить, есть ли уже ребенок, если нет, пусть руководитель создаст ребенка.

В настоящее время я запускаю дочерние элементы в модуле супервизора следующим образом:

start_child(Key) ->
    supervisor:start_child(?SERVER, [Key]).

Я хотел бы сделать что-то вроде этого (непроверенный):

start_child(Key) ->
    case supervisor:child_pid(Key) of
    Pid -> Pid;
    _ -> supervisor:start_child(?SERVER, [Key])
    end.

Какой хороший способ OTP узнать, есть ли уже дочерний элемент для Key?


person Ward Bekker    schedule 29.05.2011    source источник


Ответы (1)


Создайте супервизора, который начинает:

  • Ген_сервер. Назовем это reducer_server
  • Простой_один_за_один руководитель. Назовем это reducer_sup

Убедитесь, что ваш главный руководитель начинает работу reducer_sup до reducer_server. Состояние reducer_server может быть словарем пар Key -> Pid. Тогда reducer_server будет иметь функцию, подобную reduce(Key), которая либо находит ключ в словаре и знает соответствующий процесс, либо не находит ключ и запускает функцию вроде:

new_reduce(Key) ->
    case supervisor:start_child(reducer_sup, [Key]) of
        {ok, Pid} when is_pid(Pid) -> {ok, Pid};
        {ok, Pid, _} when is_pid(Pid) -> {ok, Pid};
        _ -> error
    end.

Просто добавьте полученный pid в свое состояние, и вы должны быть готовы к следующему вызову reduce/1. Я рекомендую прочитать это и это, чтобы лучше понять, как все эти части работают вместе. Если вы помещали этот код в производственную среду, вы можете рассмотреть такие вещи, как:

  • Что происходит, когда процессы умирают? Подсказка: проверьте живость с помощью is_process_alive/1.
  • Что произойдет, если reducer_server или reducer_sup умрет?
person David Weldon    schedule 29.05.2011