Erlang supervisor: как проверить, ответили ли все работники - PullRequest
8 голосов
/ 20 сентября 2011

У меня есть руководитель с N рабочими процессами.Как обычно, супервизор может отправить сообщение рабочему процессу, и существует handle_cast, который отправляет ответ от работника супервизору.

Как я могу проверить, что именно все N работников ответили супервизору?Можно ли реализовать это с какой-либо обработкой событий - т.е. сказать супервизору «Хорошо, все ответили», а не заставлять супервизора проверять состояние «Все N процессов ответили» каждую секунду в каком-то ETS?таблица дочернего реестра?

Ответы [ 2 ]

8 голосов
/ 20 сентября 2011

Если вы говорите об OTP supervisor, нет, вы не можете отправить сообщение работнику с него. Супервизор является очень ограниченным поведением с целью запуска , мониторинга , перезапуска и остановки процессов. Ничего другого.

Итак, чтобы решить вашу конкретную проблему, вы должны иметь процесс, который отвечает за отправку сообщения всем работникам. Этот процесс может также сохранить список всех работников в своем состоянии, «пометить» (или удалить из списка) работников, которые ответили. Вы можете достичь этого с помощью списка идентификаторов PID и получения ответов от процессов (или путем отслеживания процессов с помощью erlang:monitor/2, если они завершаются, когда они сделаны) и видеть, кто ушел.

3 голосов
/ 22 сентября 2011

Альтернатива - которая может (или не может) применяться к вашему делу - использовать поведение gen_event .

ОТКАЗ

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

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ

Итак ...

В OTP менеджер событий - это именованный объект, на который можно отправлять события.

События - это сообщения.

В диспетчере событий установлены ноль, один или несколько обработчиков событий. Когда менеджер событий получает уведомление о событии, оно будет обработано всеми установленными обработчиками событий.

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

Затем вы можете использовать функцию gen_event: sync_notify / 2 :

sync_notify является синхронным в том смысле, что он вернется нормально после событие было обработано всеми обработчиками событий.

Для получения дополнительной информации о * gen_event * посмотрите здесь и там .

...