Состояние в процессе менеджера событий OTP (не обработчик!) - PullRequest
4 голосов
/ 20 октября 2010

Может ли процесс диспетчера событий OTP (например, регистратор) иметь свое собственное состояние (например, уровень ведения журнала) и фильтровать / преобразовывать события на его основе?

Ответы [ 3 ]

1 голос
/ 14 января 2011

У меня также есть необходимость поместить какое-то состояние в сам gen_event, и моя лучшая идея на данный момент - использовать словарь процессов (get / put). Обработчики вызываются в контексте процесса gen_event, поэтому для всех вызовов обработчиков будет один и тот же словарь процесса.

Да, словари процессов - это зло, но в этом случае они кажутся менее злыми, чем альтернативы (таблица, сервер состояний).

1 голос
/ 21 октября 2010

Реализация gen_event, содержащаяся в OTP, не предоставляет средства для добавления состояния.Вы можете расширить реализацию для достижения этой цели и использовать свою реализацию вместо gen_event.Однако я бы посоветовал против этого.

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

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

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

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

Обработчики могут иметь свое собственное состояние, которое передается при каждом обратном вызове, например:

Module:handle_event(Event, State) -> Result

Фильтрация может выглядеть следующим образом (при условии, например, {level N, Content} события):

handle_event({level, Lvl, Content}, State#state{max_level=Max}) when Lvl >= Max ->
     gen_event:notify(filtered_man, Content);

Состояние может быть изменено либо специальными событиями, gen_event:call\3,4 (предпочтительно) или сообщениями, обработанными handle_info.

Подробнее см. Поведение Gen_Event и gen_event (3)

0 голосов
/ 21 октября 2010

Когда вы start_link gen_event обрабатываете - то, что вы всегда должны делать через супервизора - вы можете просто указать имя для нового процесса, если вам нужно / хотите, чтобы он был зарегистрирован. Насколько я вижу, нет способа инициировать какое-либо state с использованием этого поведения.

Конечно, вы можете написать свое собственное поведение поверх gen_event или простого gen_server.

В качестве альтернативы вы можете использовать отдельный процесс gen_event для каждого уровня отладки . Или вы можете просто отфильтровать сообщения в обработчиках.

...