Erlang: разница между использованием Gen server: cast / 2 и стандартной передачей сообщений
Я работал, хотя проблема и заметил некоторый код, где предыдущий программист передавал сообщения, используя стандартное соглашение PID ! Сообщение. Я использую gen_server: cast/2. Мне было интересно, может ли кто-нибудь объяснить мне критические различия и соображения при выборе между ними?
2 ответов
есть несколько незначительных различий:
- очевидно, что gen_server обрабатывает Броски в
handle_cast
и "нормальные" сообщения вhandle_info
. - бросок никогда не терпит неудачу; он всегда возвращается
ok
. Отправка сообщения с!
выдаетbadarg
если вы отправляете сообщение атому, который в настоящее время не зарегистрирован процессом. (Отправка сообщения в pid никогда не вызывает ошибки, даже если процесс мертв.) - если gen_server работает на удаленном узле, который в настоящее время не подключен к локальному узлу, затем
gen_server:cast
появится фоновый процесс, чтобы установить соединение и отправить сообщение, и сразу же вернуться, в то время как!
возвращает только после установления соединения. (См. кодgen_server:do_send
.)
что касается того, когда выбрать один или другой, это в основном вопрос вкуса. Я бы сказал, что если сообщение можно рассматривать как асинхронную функцию API для gen_server, то оно должно используйте cast,и имеют определенную функцию API в модуле обратного вызова gen_server. То есть вместо того, чтобы звонить gen_server:cast
прямо, вот так:
gen_server:cast(foo_proc, {some_message, 42})
вызов функции:
foo_proc:some_message(42)
и реализовать эту функцию, как прямой бросок выше. Это инкапсулирует конкретный протокол gen_server внутри своего собственного модуля.
на мой взгляд, "простые" сообщения будут использоваться для событий, в отличие от вызовов API. Примером может служить мониторинг сообщений,{'DOWN', Ref, process, Id, Reason}
, и мероприятий подобного рода, которые могут произойти в вашей системе.
в дополнение к legoscia post Я бы сказал, что легче отслеживать выделенную функцию API, чем сообщения. Особенно в среде prod.