我可以从远程节点调用GenServer客户端函数吗?



我在远程节点上有一个GenServer,模块中同时具有实现和客户端功能。我可以以某种方式远程使用 GenServer 客户端功能吗?

使用GenServer.call({RemoteProcessName, :"app@remoteNode"}, :get)工作是我期望的,但很麻烦。

如果我想清理它,我认为我必须在调用(客户端(节点上编写客户端函数是否正确?

您可以使用: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;博士

是的

讨论

有PID,消息,监视器和链接。仅此而已,仅此而已。那是你的宇宙。(除非你进入运行时实现的一些相当深奥的方面 - 但在EVM语言表示的抽象级别,前面所述的元素(应该(构成你的宇宙。

在 Erlang 环境中(无论是本地还是分布在网格中(,任何PID 都可以发送发送到任何其他PID 的消息(无需中间人(,以及建立监视器等。

gen_server:cast发送gen_server打包的消息(因此它将以调用handle_cast/2的形式到达(。gen_server:call/2建立监视器和用于接收标记回复的超时。简单地做PID ! SomeMessagegen_server:cast(发送消息(基本上相同,而没有任何gen_server机制(从混乱到抽象为接口(。

仅此而已。

考虑到这一点,您当然可以跨节点使用gen_server:call/2,只要它们通过 disterl 连接到集群/网格中即可。两个断开连接的节点必须以不同的方式(网络套接字(进行通信,并且不知道彼此的PID内部映射,但只要使用disterl,它们都很容易在它们之间转换PID。命名进程是事情变得有点棘手的地方,但这就是global模块和实用程序(如gproc(的目的(尽管对此类设施的依赖超过一定点通常表明存在架构问题(。

当然,仅仅因为来自任何节点的 PID 可以与来自另一个节点的 PID 通信并不总是意味着它们应该这样做。当您开始发送高频或大型消息(大量gen_server:call(时,网络的物理拓扑(带宽,延迟,抖动(就会发挥作用,并且您始终必须考虑分区容错 - 但是对于卸载繁重的工作(很少(或在非常大的系统中对子系统进行物理分区(更常见(,直接发送消息是一种非常简单的方法,可以将为单个节点编码的程序分发到各个节点一个集群。

(考虑到所有这些,很少看到使用的 rpc 模块。

最新更新