查看源码 rpc (kernel v10.2)
远程过程调用服务。
此模块包含类似于远程过程调用的服务。它还包含广播工具和并行评估器。远程过程调用是一种在远程节点上调用函数并收集答案的方法。它用于收集远程节点上的信息,或在远程节点上运行具有某些特定副作用的函数。
注意
rpc:call/4
及其相关函数使得很难区分成功的结果、引发的异常和其他错误。由于兼容性原因,这无法更改。从 OTP 23 开始,引入了一个新的模块erpc
,以便提供一个 API,使得可以区分不同的结果。erpc
模块提供了rpc
模块中可用功能的一个子集(但却是核心子集)。erpc
实现还提供了比原始rpc
实现更具可扩展性和更好性能的实现。但是,自从引入erpc
以来,rpc
模块使用erpc
实现了其大部分核心功能,因此与erpc
相比,rpc
模块在可扩展性和性能方面不会受到影响。
注意
有关分布式信号的一些重要信息,请参阅《Erlang 参考手册》Processes 章中的“通过分布进行阻塞信号”部分。例如,阻塞信号会导致
rpc
中的超时显着延迟。
摘要
类型
由 async_call/4
返回的不透明值。
函数
将消息 Msg
异步广播到指定节点上注册的进程 Name
。
实现带有 promise 的调用流,这是一种 RPC,它不会暂停调用者,直到结果完成。相反,返回一个键,该键稍后可用于收集值。该键可以被视为交付答案的承诺。
与调用 rpc:call(Node, Module, Function, Args, Timeout)
相同,但例外情况是,它还会阻止其他 rpc:block_call/5
操作在节点 Node
上并发执行。
在节点 Node
上评估 apply(Module, Function, Args)
,并返回相应的值 Res
,如果调用失败,则返回 {badrpc, Reason}
。与调用 rpc:call(Node, Module, Function, Args, infinity)
相同。
在节点 Node
上评估 apply(Module, Function, Args)
,并返回相应的值 Res
,如果调用失败,则返回 {badrpc, Reason}
。Timeout
是一个以毫秒为单位的超时值。如果调用超时,则 Reason
为 timeout
。
在节点 Node
上评估 apply(Module, Function, Args)
。不会传递任何响应,并且调用进程不会暂停,直到评估完成,就像 call/4,5
的情况一样。
在指定的节点上评估 apply(Module, Function, Args)
。不会收集任何答案。
可用于与指定节点上名为 Name
的服务器进行交互。假定服务器接收格式为 {From, Msg}
的消息,并使用 From ! {Name, Node, Reply}
进行回复,其中 Node
是服务器所在的节点的名称。该函数返回 {Replies, BadNodes}
,其中 Replies
是所有 Reply
值的列表,而 BadNodes
是以下之一
与 RPC 相比,多重调用是从一个客户端并发发送到多个服务器的 RPC。这对于从一组节点收集信息,或在多个节点上调用函数以实现某些副作用非常有用。它在语义上与在所有节点上迭代进行一系列 RPC 相同,但多重调用更快,因为所有请求都是同时发送的,并且会随着它们的返回而逐个收集。
yield/1
的非阻塞版本。当计算完成时,它返回元组 {value, Val}
,或者当 Timeout
毫秒过去时,返回 timeout
。
对于 FuncCalls
中的每个元组,在网络中的某个节点上评估 apply(Module, Function, Args)
。返回返回值列表,顺序与 FuncCalls
中的顺序相同。
ERTS 中 BIF erlang:process_info/1
的位置透明版本。
ERTS 中 BIF erlang:process_info/2
的位置透明版本。
对于 List1
中的每个元素 Elem
,并行评估 apply(Module, Function, [Elem|ExtraArgs])
。返回返回值列表,顺序与 List1
中的顺序相同。
将消息 Msg
同步广播到指定节点上注册的进程 Name
。
可用于与节点 Node
上名为 Name
的服务器进行交互。假定服务器接收格式为 {From, Msg}
的消息,并使用 From ! {ReplyWrapper, Node, Reply}
进行回复。此函数会进行此类服务器调用,并确保将整个调用打包到原子事务中,该事务要么成功,要么失败。它永远不会挂起,除非服务器本身挂起。
从之前的 async_call/4
返回承诺的答案。如果答案可用,则立即返回。否则,调用进程将暂停,直到答案从 Node
到达。
类型
-opaque key()
由 async_call/4
返回的不透明值。
函数
将消息 Msg
异步广播到指定节点上注册的进程 Name
。
-spec async_call(Node, Module, Function, Args) -> Key when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], Key :: key().
实现带有 promise 的调用流,这是一种 RPC,它不会暂停调用者,直到结果完成。相反,返回一个键,该键稍后可用于收集值。该键可以被视为交付答案的承诺。
在这种情况下,返回键 Key
,该键可在后续调用 yield/1
或 nb_yield/1,2
中使用,以检索在节点 Node
上评估 apply(Module, Function, Args)
的值。
注意
如果您希望能够区分结果,则可能需要考虑使用
erpc
模块中的erpc:send_request()
函数。这还使您能够以其他有用的方式检索结果。
注意
yield/1
和nb_yield/1,2
必须由发出此函数的同一进程调用,否则它们永远不会正确产生。
注意
您不能对将执行
apply()
的进程做任何假设。它可能是rpc
服务器、另一个服务器或新生成的进程。
-spec block_call(Node, Module, Function, Args) -> Res | {badrpc, Reason} when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], Res :: term(), Reason :: term().
与调用 rpc:block_call(Node, Module, Function, Args, infinity)
相同。
-spec block_call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason} when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], Res :: term(), Reason :: term(), Timeout :: 0..4294967295 | infinity.
与调用 rpc:call(Node, Module, Function, Args, Timeout)
相同,但例外情况是,它还会阻止其他 rpc:block_call/5
操作在节点 Node
上并发执行。
警告
请注意,它还会阻止除
rpc:block_call/5
操作之外的其他操作,因此请谨慎使用。
-spec call(Node, Module, Function, Args) -> Res | {badrpc, Reason} when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], Res :: term(), Reason :: term().
在节点 Node
上评估 apply(Module, Function, Args)
,并返回相应的值 Res
,如果调用失败,则返回 {badrpc, Reason}
。与调用 rpc:call(Node, Module, Function, Args, infinity)
相同。
-spec call(Node, Module, Function, Args, Timeout) -> Res | {badrpc, Reason} when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()], Res :: term(), Reason :: term(), Timeout :: 0..4294967295 | infinity.
在节点 Node
上评估 apply(Module, Function, Args)
,并返回相应的值 Res
,如果调用失败,则返回 {badrpc, Reason}
。Timeout
是一个以毫秒为单位的超时值。如果调用超时,则 Reason
为 timeout
。
如果回复在调用超时后到达,则不会有任何消息污染调用者的消息队列。
注意
如果您希望能够区分结果,则可能需要考虑使用
erpc
模块中的erpc:call()
函数。
注意
以下是返回值的详细信息。
{badrpc, Reason}
将在以下情况下返回:
- 被调用的函数因
exit
异常而失败。- 被调用的函数因
error
异常而失败。- 被调用的函数返回一个匹配
{'EXIT', _}
的项。- 被调用的函数
throw
一个匹配{'EXIT', _}
的项。
Res
将在以下情况下返回:
- 被调用的函数正常返回,其返回值与
{'EXIT',_}
不匹配。- 被调用的函数
throw
一个与{'EXIT',_}
不匹配的项。
注意
你不能对执行
apply()
的进程做 *任何* 假设。它可能是调用进程本身,一个rpc
服务器,另一个服务器,或者是一个新生成的进程。
-spec cast(Node, Module, Function, Args) -> true when Node :: node(), Module :: module(), Function :: atom(), Args :: [term()].
在节点 Node
上评估 apply(Module, Function, Args)
。不会传递任何响应,并且调用进程不会暂停,直到评估完成,就像 call/4,5
的情况一样。
注意
您不能对将执行
apply()
的进程做任何假设。它可能是rpc
服务器、另一个服务器或新生成的进程。
-spec eval_everywhere(Module, Function, Args) -> abcast when Module :: module(), Function :: atom(), Args :: [term()].
等效于 eval_everywhere([node()|nodes()], Module, Function, Args)
。
-spec eval_everywhere(Nodes, Module, Function, Args) -> abcast when Nodes :: [node()], Module :: module(), Function :: atom(), Args :: [term()].
在指定的节点上评估 apply(Module, Function, Args)
。不会收集任何答案。
-spec multi_server_call(Nodes, Name, Msg) -> {Replies, BadNodes} when Nodes :: [node()], Name :: atom(), Msg :: term(), Replies :: [Reply :: term()], BadNodes :: [node()].
可用于与指定节点上名为 Name
的服务器进行交互。假定服务器接收格式为 {From, Msg}
的消息,并使用 From ! {Name, Node, Reply}
进行回复,其中 Node
是服务器所在的节点的名称。该函数返回 {Replies, BadNodes}
,其中 Replies
是所有 Reply
值的列表,而 BadNodes
是以下之一
- 不存在的节点列表
- 服务器不存在的节点列表
- 服务器在发送任何回复之前终止的节点列表。
-spec multicall(Module, Function, Args) -> {ResL, BadNodes} when Module :: module(), Function :: atom(), Args :: [term()], ResL :: [Res :: term() | {badrpc, Reason :: term()}], BadNodes :: [node()].
等效于 multicall([node()|nodes()], Module, Function, Args, infinity)
。
-spec multicall(Nodes, Module, Function, Args) -> {ResL, BadNodes} when Nodes :: [node()], Module :: module(), Function :: atom(), Args :: [term()], ResL :: [Res :: term() | {badrpc, Reason :: term()}], BadNodes :: [node()]; (Module, Function, Args, Timeout) -> {ResL, BadNodes} when Module :: module(), Function :: atom(), Args :: [term()], Timeout :: 0..4294967295 | infinity, ResL :: [Res :: term() | {badrpc, Reason :: term()}], BadNodes :: [node()].
等效于 multicall(Nodes, Module, Function, Args, infinity)
。
等同于 multicall([node()|nodes()], Module, Function, Args, Timeout)
。
-spec multicall(Nodes, Module, Function, Args, Timeout) -> {ResL, BadNodes} when Nodes :: [node()], Module :: module(), Function :: atom(), Args :: [term()], Timeout :: 0..4294967295 | infinity, ResL :: [Res :: term() | {badrpc, Reason :: term()}], BadNodes :: [node()].
与 RPC 相比,多重调用是从一个客户端并发发送到多个服务器的 RPC。这对于从一组节点收集信息,或在多个节点上调用函数以实现某些副作用非常有用。它在语义上与在所有节点上迭代进行一系列 RPC 相同,但多重调用更快,因为所有请求都是同时发送的,并且会随着它们的返回而逐个收集。
该函数在指定的节点上评估 apply(Module, Function, Args)
并收集答案。它返回 {ResL, BadNodes}
,其中 BadNodes
是不存在的节点列表,ResL
是返回值列表,对于失败的调用则返回 {badrpc, Reason}
。Timeout
是一个以毫秒为单位的时间(整数),或者 infinity
。
以下示例在网络中的所有节点上加载新对象代码时很有用,并且表明 RPC 可能会产生一些副作用
%% Find object code for module Mod
{Mod, Bin, File} = code:get_object_code(Mod),
%% and load it on all nodes including this one
{ResL, _} = rpc:multicall(code, load_binary, [Mod, File, Bin]),
%% and then maybe check the ResL list.
注意
如果你想区分结果,你可能需要考虑使用来自
erpc
模块的erpc:multicall()
函数。
注意
你不能对执行
apply()
的进程做 *任何* 假设。它可能是调用进程本身,一个rpc
服务器,另一个服务器,或者是一个新生成的进程。
-spec nb_yield(Key) -> {value, Val} | timeout when Key :: key(), Val :: (Res :: term()) | {badrpc, Reason :: term()}.
等效于 nb_yield(Key, 0)
。
-spec nb_yield(Key, Timeout) -> {value, Val} | timeout when Key :: key(), Timeout :: 0..4294967295 | infinity, Val :: (Res :: term()) | {badrpc, Reason :: term()}.
yield/1
的非阻塞版本。当计算完成时,它返回元组 {value, Val}
,或者当 Timeout
毫秒过去时,返回 timeout
。
有关 Val 的更多详细信息,请参阅 call/4
中的说明。
注意
此函数必须由与发起
async_call/4
的进程相同的进程调用,否则它只会返回timeout
。
-spec parallel_eval(FuncCalls) -> ResL when FuncCalls :: [{Module, Function, Args}], Module :: module(), Function :: atom(), Args :: [term()], ResL :: [term()].
对于 FuncCalls
中的每个元组,在网络中的某个节点上评估 apply(Module, Function, Args)
。返回返回值列表,顺序与 FuncCalls
中的顺序相同。
ERTS 中 BIF erlang:process_info/1
的位置透明版本。
-spec pinfo(Pid, Item) -> {Item, Info} | undefined | [] when Pid :: pid(), Item :: atom(), Info :: term(); (Pid, ItemList) -> [{Item, Info}] | undefined | [] when Pid :: pid(), Item :: atom(), ItemList :: [Item], Info :: term().
ERTS 中 BIF erlang:process_info/2
的位置透明版本。
-spec pmap(FuncSpec, ExtraArgs, List1) -> List2 when FuncSpec :: {Module, Function}, Module :: module(), Function :: atom(), ExtraArgs :: [term()], List1 :: [Elem :: term()], List2 :: [term()].
对于 List1
中的每个元素 Elem
,并行评估 apply(Module, Function, [Elem|ExtraArgs])
。返回返回值列表,顺序与 List1
中的顺序相同。
-spec sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes} when Name :: atom(), Msg :: term(), Nodes :: [node()], GoodNodes :: [node()], BadNodes :: [node()].
将消息 Msg
同步广播到指定节点上注册的进程 Name
。
返回 {GoodNodes, BadNodes}
,其中 GoodNodes
是将 Name
作为注册进程的节点列表。
该函数是同步的,因为它知道当调用返回时,所有服务器都已收到消息。无法知道服务器是否已处理消息。
在此函数返回后发送给服务器的任何进一步消息都将在该消息之后被所有服务器接收。
-spec server_call(Node, Name, ReplyWrapper, Msg) -> Reply | {error, Reason} when Node :: node(), Name :: atom(), ReplyWrapper :: term(), Msg :: term(), Reply :: term(), Reason :: nodedown.
可用于与节点 Node
上名为 Name
的服务器进行交互。假定服务器接收格式为 {From, Msg}
的消息,并使用 From ! {ReplyWrapper, Node, Reply}
进行回复。此函数会进行此类服务器调用,并确保将整个调用打包到原子事务中,该事务要么成功,要么失败。它永远不会挂起,除非服务器本身挂起。
该函数返回服务器 Name
生成的答案 Reply
,或者返回 {error, Reason}
。
从之前的 async_call/4
返回承诺的答案。如果答案可用,则立即返回。否则,调用进程将暂停,直到答案从 Node
到达。
注意
此函数必须由与发起
async_call/4
的进程相同的进程调用,否则它将永远不会返回。
有关返回值的更多详细信息,请参阅 call/4
中的说明。