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

Erlang 我可以从远程节点调用GenServer客户端函数吗?,erlang,elixir,otp,gen-server,Erlang,Elixir,Otp,Gen Server,我在远程节点上有一个GenServer,模块中有实现和客户端功能。我可以远程使用GenServer客户端功能吗 使用GenServer.call{RemoteProcessName,:app@remoteNode},:我希望它能工作,但它很麻烦 如果我想清理一下,我认为我必须在调用客户机节点上编写客户机函数,对吗?您可以使用这些函数 :rpc.call(:"app@remoteNode", MyModule, :some_func, [arg1, arg2]) 您可以使用这些函数 :rpc.c

我在远程节点上有一个GenServer,模块中有实现和客户端功能。我可以远程使用GenServer客户端功能吗

使用GenServer.call{RemoteProcessName,:app@remoteNode},:我希望它能工作,但它很麻烦

如果我想清理一下,我认为我必须在调用客户机节点上编写客户机函数,对吗?

您可以使用这些函数

:rpc.call(:"app@remoteNode", MyModule, :some_func, [arg1, arg2])
您可以使用这些函数

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

对于大量呼叫,最好使用gen_server:call/2-3。
如果您想使用rpc:call/4-5,您应该知道它只是每个节点上一个名为rex的进程,用于处理所有请求。因此,如果它正在运行一个Mod:FuncArg1、Arg2、Argn,则此时无法响应其他请求

对于大量呼叫,最好使用gen_server:call/2-3。 如果您想使用rpc:call/4-5,您应该知道它只是每个节点上一个名为rex的进程,用于处理所有请求。因此,如果它正在运行一个Mod:FuncArg1、Arg2、Argn,则此时无法响应其他请求

TL;博士

讨论

有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。命名过程是事情变得有点棘手的地方,但这是全局模块和实用程序(如gproc)的目的,尽管在某一点之外对此类工具的依赖通常是架构问题的一个迹象

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

考虑到所有这些,很少看到使用rpc模块;博士

讨论

有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。命名过程是事情变得有点棘手的地方,但这是全局模块和实用程序(如gproc)的目的,尽管在某一点之外对此类工具的依赖通常是架构p的一个指示 问题

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


考虑到所有这些,使用rpc模块有点罕见。

知道这一点很有用,但这是否意味着如果我计划使用GenServer回复多个客户端进程,我必须放弃在GenServer中使用客户端函数?事实上,来自其他语言的人习惯使用rpc模块,但我从来没有找到过它的用例,因为你可以这样做!消息,甚至直接在单独的节点上生成一个进程,只要它可以访问您在本地调用它的相同代码。这不是关于一个gen_服务器。因为一个gen_服务器通常可以按顺序发送回复请求。它是关于在远程节点上有几个gen_服务器。所以,当您使用rpc时,此时只有一个gen_服务器可以响应请求。如果您不想经常断开与远程节点的连接,您可以在当前节点上动态地从远程节点加载该模块并使用其功能。了解这一点很有用,但这是否意味着我必须放弃在GenServer中使用客户端功能,如果我计划使用GenServer来回复多个客户端进程?确实-rpc模块是来自其他语言的人惯常使用的,但我从来没有找到它的用例,因为您可以只使用Pid!消息,甚至直接在单独的节点上生成一个进程,只要它可以访问您在本地调用它的相同代码。这不是关于一个gen_服务器。因为一个gen_服务器通常可以按顺序发送回复请求。它是关于在远程节点上有几个gen_服务器。所以,当您使用rpc时,此时只有一个gen_服务器可以响应请求。如果不想经常断开与远程节点的连接,可以在当前节点上动态地从远程节点加载该模块并使用其功能。