查看源码 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 是一个以毫秒为单位的超时值。如果调用超时,则 Reasontimeout

在节点 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 返回的不透明值。

函数

-spec abcast(Name, Msg) -> abcast when Name :: atom(), Msg :: term().

等效于 abcast([node()|nodes()], Name, Msg)

链接到此函数

abcast(Nodes, Name, Msg)

查看源码
-spec abcast(Nodes, Name, Msg) -> abcast when Nodes :: [node()], Name :: atom(), Msg :: term().

将消息 Msg 异步广播到指定节点上注册的进程 Name

链接到此函数

async_call(Node, Module, Function, Args)

查看源码
-spec async_call(Node, Module, Function, Args) -> Key
                    when
                        Node :: node(),
                        Module :: module(),
                        Function :: atom(),
                        Args :: [term()],
                        Key :: key().

实现带有 promise 的调用流,这是一种 RPC,它不会暂停调用者,直到结果完成。相反,返回一个键,该键稍后可用于收集值。该键可以被视为交付答案的承诺。

在这种情况下,返回键 Key,该键可在后续调用 yield/1nb_yield/1,2 中使用,以检索在节点 Node 上评估 apply(Module, Function, Args) 的值。

注意

如果您希望能够区分结果,则可能需要考虑使用 erpc 模块中的 erpc:send_request() 函数。这还使您能够以其他有用的方式检索结果。

注意

yield/1nb_yield/1,2 必须由发出此函数的同一进程调用,否则它们永远不会正确产生。

注意

您不能对将执行 apply() 的进程做任何假设。它可能是 rpc 服务器、另一个服务器或新生成的进程。

链接到此函数

block_call(Node, Module, Function, Args)

查看源码
-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) 相同。

链接到此函数

block_call(Node, Module, Function, Args, Timeout)

查看源码
-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 操作之外的其他操作,因此请谨慎使用。

链接到此函数

call(Node, Module, Function, Args)

查看源码
-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) 相同。

链接到此函数

call(Node, Module, Function, Args, Timeout)

查看源码
-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 是一个以毫秒为单位的超时值。如果调用超时,则 Reasontimeout

如果回复在调用超时后到达,则不会有任何消息污染调用者的消息队列。

注意

如果您希望能够区分结果,则可能需要考虑使用 erpc 模块中的 erpc:call() 函数。

注意

以下是返回值的详细信息。

{badrpc, Reason} 将在以下情况下返回:

  • 被调用的函数因 exit 异常而失败。
  • 被调用的函数因 error 异常而失败。
  • 被调用的函数返回一个匹配 {'EXIT', _} 的项。
  • 被调用的函数 throw 一个匹配 {'EXIT', _} 的项。

Res 将在以下情况下返回:

  • 被调用的函数正常返回,其返回值与 {'EXIT',_} 不匹配。
  • 被调用的函数 throw 一个与 {'EXIT',_} 不匹配的项。

注意

你不能对执行 apply() 的进程做 *任何* 假设。它可能是调用进程本身,一个 rpc 服务器,另一个服务器,或者是一个新生成的进程。

链接到此函数

cast(Node, Module, Function, Args)

查看源码
-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 服务器、另一个服务器或新生成的进程。

链接到此函数

eval_everywhere(Module, Function, Args)

查看源码
-spec eval_everywhere(Module, Function, Args) -> abcast
                         when Module :: module(), Function :: atom(), Args :: [term()].

等效于 eval_everywhere([node()|nodes()], Module, Function, Args)

链接到此函数

eval_everywhere(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)。不会收集任何答案。

链接到此函数

multi_server_call(Name, Msg)

查看源码
-spec multi_server_call(Name, Msg) -> {Replies, BadNodes}
                           when
                               Name :: atom(),
                               Msg :: term(),
                               Replies :: [Reply :: term()],
                               BadNodes :: [node()].

等效于 multi_server_call([node()|nodes()], Name, Msg)

链接到此函数

multi_server_call(Nodes, Name, Msg)

查看源码
-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 是以下之一

  • 不存在的节点列表
  • 服务器不存在的节点列表
  • 服务器在发送任何回复之前终止的节点列表。
链接到此函数

multicall(Module, Function, Args)

查看源码
-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)

链接到此函数

multicall(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)

链接到此函数

nb_yield(Key, Timeout)

查看源码
-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

链接到此函数

parallel_eval(FuncCalls)

查看源码
-spec parallel_eval(FuncCalls) -> ResL
                       when
                           FuncCalls :: [{Module, Function, Args}],
                           Module :: module(),
                           Function :: atom(),
                           Args :: [term()],
                           ResL :: [term()].

对于 FuncCalls 中的每个元组,在网络中的某个节点上评估 apply(Module, Function, Args)。返回返回值列表,顺序与 FuncCalls 中的顺序相同。

-spec pinfo(Pid) -> [{Item, Info}] | undefined when Pid :: pid(), Item :: atom(), Info :: term().

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 的位置透明版本。

链接到此函数

pmap(FuncSpec, ExtraArgs, List1)

查看源码
-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(Name, Msg) -> {GoodNodes, BadNodes}
                when Name :: atom(), Msg :: term(), GoodNodes :: [node()], BadNodes :: [node()].

等效于 sbcast([node()|nodes()], Name, Msg)

链接到此函数

sbcast(Nodes, Name, Msg)

查看源码
-spec sbcast(Nodes, Name, Msg) -> {GoodNodes, BadNodes}
                when
                    Name :: atom(),
                    Msg :: term(),
                    Nodes :: [node()],
                    GoodNodes :: [node()],
                    BadNodes :: [node()].

将消息 Msg 同步广播到指定节点上注册的进程 Name

返回 {GoodNodes, BadNodes},其中 GoodNodes 是将 Name 作为注册进程的节点列表。

该函数是同步的,因为它知道当调用返回时,所有服务器都已收到消息。无法知道服务器是否已处理消息。

在此函数返回后发送给服务器的任何进一步消息都将在该消息之后被所有服务器接收。

链接到此函数

server_call(Node, Name, ReplyWrapper, Msg)

查看源码
-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}

-spec yield(Key) -> Res | {badrpc, Reason} when Key :: key(), Res :: term(), Reason :: term().

从之前的 async_call/4 返回承诺的答案。如果答案可用,则立即返回。否则,调用进程将暂停,直到答案从 Node 到达。

注意

此函数必须由与发起 async_call/4 的进程相同的进程调用,否则它将永远不会返回。

有关返回值的更多详细信息,请参阅 call/4 中的说明。