Могу ли я вызвать функции клиента GenServer с удаленного узла?

У меня есть GenServer на удаленном узле с функциями реализации и клиента в модуле. Могу ли я использовать функции клиента GenServer удаленно?

С помощью GenServer.call({RemoteProcessName, :"app@remoteNode"}, :get) работает, я ожидаю, но это громоздко.

Если я хочу очистить это, я прав, думая, что я должен был бы написать функции клиента на вызывающем (клиентском) узле?

3 ответа

Решение

Вы можете использовать :rpc.call/{4,5} функции.

:rpc.call(:"app@remoteNode", MyModule, :some_func, [arg1, arg2])

Для большого количества звонков, лучше для пользователя gen_server:call/2-3,
Если вы хотите использовать rpc:call/4-5, вы должны знать, что это всего лишь один процесс с именем rex на каждом узле для обработки всех запросов. Так что, если он работает один Mod:Func(Arg1, Arg2, Argn), Он не может ответить на другой запрос в это время!

TL;DR

да

обсуждение

Есть PID, сообщения, мониторы и ссылки. Ни больше ни меньше. Это твоя вселенная. (Если только вы не попадаете в некоторые довольно эзотерические аспекты реализации времени выполнения - но на уровне абстракции, представленном языками EVM, ранее заявленные элементы (должны) составляют вашу вселенную.)

В среде Erlang (локальной или распределенной в сетке) любой PID может отправлять сообщение, адресованное любому другому PID (посредник не требуется), а также устанавливать мониторы и так далее.

gen_server:cast отправляет упакованное сообщение gen_server (таким образом, оно придет в виде handle_cast/2 будет вызвано). gen_server:call/2 устанавливает монитор и тайм-аут для получения помеченного ответа. Просто делаю PID ! SomeMessage делает по существу то же самое, что и gen_server:cast (отправляет сообщение) без какого-либо механизма gen_server, стоящего за ним (сложнее абстрагировать как интерфейс).

Это все, что нужно сделать.

Имея это в виду, конечно, вы можете использовать gen_server:call/2 через узлы, если они соединены в кластер / сетку через disterl. Два отключенных узла должны были бы взаимодействовать по-разному (сетевые сокеты) и не знали бы о внутреннем сопоставлении PID друг друга, но пока используется disterl, все они довольно легко переводят PID между собой. Именованные процессы - то, где вещи становятся немного хитрыми, но это является целью global модуль и утилиты, такие как gproc (хотя зависимость от таких объектов за определенной точкой обычно является признаком архитектурной проблемы).

Конечно, то, что PID любого узла может связываться с PID другого узла, не всегда означает, что они должны это делать. Физическая топология сети (пропускная способность, задержка, дрожание) вступает в игру, когда вы начинаете отправлять высокочастотные или большие сообщения (много gen_server:call s), и вы всегда должны думать о допустимости разбиения - но для разгрузки тяжелых видов работ (редко) или физического разделения подсистем в очень большой системе (более часто) прямая отправка сообщений - очень простой способ взять программу, закодированную для одного узла, и распределить ее по кластеру.

(Учитывая все это, довольно редко можно увидеть используемый модуль rpc.)

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