gen_server: вызов против простого вызова функции - PullRequest
0 голосов
/ 04 июля 2018

Допустим, в gen_server запущены два процесса (запущенных супервизором). Один вызывает функцию в другом, как это: brother:function(Param). Это также может сделать gen_server:call(brother, Param). Каковы варианты использования для каждого? В обоих случаях первый процесс ожидает завершения функции в brother, поэтому я не понимаю, когда следует использовать каждую из них.

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Нет никакой разницы напрямую. Однако использование gen_server:call (или cast) напрямую означает, что вы связываете свои другие модули с внутренними частями gen_server. Представьте себе, что позже вы захотите изменить регистрацию brother, чтобы она использовала что-то другое (например, внешнюю библиотеку, такую ​​как gproc). Теперь вам нужно найти и найти все места, где вы использовали gen_server:call(brother, ...) и исправить это, и дублируют много кода для получения имени сервера и так далее. В целом это просто намного проще brother:function(...)

То же самое относится к изменению внутренней структуры вызовов или приведения. Становится намного проще просто передать все в качестве аргументов функции, а затем использовать эту функцию для построения параметров. Например, скажем, вы используете эту функцию для создания записи, которая является внутренней по отношению к модулю.

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

0 голосов
/ 04 июля 2018

первый процесс ожидает завершения функции в брате

Нет, это не так. Или, скорее, это зависит от того, как определяется function. Это часто будет что-то вроде

function(Param) -> gen_server:call(?MODULE, {function, Param}) 
%% or gen_server:call(?MODULE, Param) if there's only one kind of request

, а фактическая реализация будет в brother:handle_call.

Очевидно, что в этом случае нет разницы между результатами вызова brother:function(Param) или выполнением gen_server:call вручную, но вызов brother:function - это лучший метод: он позволяет скрыть детали, вызывающие модуль не знает бизнеса и позволяет brother поменять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...