Могу ли я обработать любое полученное сообщение в обратных вызовах состояния gen_fsm?

Я заметил, что сообщения, отправленные на pid процесса gen_fsm, сопоставляются в обратных вызовах состояния как события. Это просто случайно или я могу положиться на эту функцию?

Обычно я ожидал, что общие сообщения, отправленные gen_fsm, будут отображаться в обратном вызове handle_info/3, и подумал, что мне придется повторно отправить его с помощью gen_fsm:send_event.

Пытается ли gen_fsm сопоставить сообщение сначала с обратным вызовом состояния, а затем всегда с обратным вызовом handle_info/3? Или только если он не соответствует предложению обратного вызова состояния?

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

Таким образом, в основном вопрос также можно сформулировать так: как правильно обрабатывать полученные сообщения как события в функциях состояния gen_fsm?


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

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

Я не уверен, улучшит ли это текущую платформу, в которую должен вписываться упомянутый gen_fsm: стеки различных протоколов, где каждый уровень вызывает функцию connect() для присоединения (и иногда запуска) нижнего уровня. Пакеты отправляются на нижние уровни при вызове функции (отправка) и принимаются receiveсоставление сообщения. Очень похоже на gen_tcp.

Глядя на код для gen_fsm, я уже понял, что общие сообщения передаются только на handle_info, поэтому остается только вопрос вызова функции состояния напрямую из обратного вызова handle_info/3 или повторной отправки с использованием gen_fsm:send_event.

1 ответ

Решение

Общие сообщения обрабатываются обратным вызовом handle_info, если в вашем коде нет ничего подобного:

handle_info (Info, StateName, StateData) ->? МОДУЛЬ:StateName(Info, StateData).

Что позволяет избежать повторной отправки, но я не рекомендую ни это, ни повторную отправку.

Доставка событий исключительно посредством вызовов API, инкапсулирующих send_event/sync_send_event/send_all_state_event/sync_send_all_state_event, делает протокол явным. Что является правильным, так как его легче понять, поддерживать и документировать с помощью edoc.

Другие вопросы по тегам