檢視原始碼 erpc (核心 v10.2)

增強型遠端程序呼叫

此模組提供類似遠端程序呼叫的服務。遠端程序呼叫是一種在遠端節點上呼叫函數並收集答案的方法。它用於收集遠端節點上的資訊,或在遠端節點上執行具有特定副作用的函數。

這是 rpc 模組提供的操作的增強子集。所謂的增強,是指它可以區分傳回值、引發的異常和其他錯誤。erpc 也比原始的 rpc 實作具有更好的效能和可擴展性。然而,目前的 rpc 模組將在可能的情況下利用 erpc 來提供這些特性。

為了使 erpc 操作成功,遠端節點也需要支援 erpc。通常只有 OTP 23 的普通 Erlang 節點才支援 erpc

請注意,使用者有責任確保在相關節點上可以使用透過 erpc 執行的正確程式碼。

注意

關於分散式訊號的一些重要資訊,請參閱《Erlang 參考手冊》中「程序」章節的「分散式上的封鎖訊號」部分。封鎖訊號可能會導致 erpc 中的逾時顯著延遲。

摘要

類型

不透明的請求識別碼。有關更多資訊,請參閱 send_request/4

不透明的請求識別碼集合(request_id/0),其中每個請求識別碼都可以與使用者選擇的標籤相關聯。有關更多資訊,請參閱 reqids_new/0

erpc 函數使用的逾時時間。

函數

在節點 Node 上評估 apply(Module, Function, Args) 並傳回對應的值 ResultTimeout 設定 call 操作完成的最長時間限制。

在節點 Node 上評估 apply(Module, Function, Args)。不會將回應傳遞給呼叫程序。cast() 在發送 cast 請求後立即傳回。除了錯誤的引數之外,任何失敗都會被靜默忽略。

檢查訊息是否是對呼叫程序先前使用 send_request/4 發出的 call 請求的回應。

檢查訊息是否是對應於儲存在 RequestIdCollection 中的請求識別碼的 call 請求的回應。RequestIdCollection 的所有請求識別碼都必須對應於使用 send_request/4send_request/6 發出的請求,且所有請求都必須由呼叫此函數的程序發出。

在多個節點上平行執行多個 call 操作。

在節點 Nodes 上評估 apply(Module, Function, Args)。不會將回應傳遞給呼叫程序。multicast() 在發送 cast 請求後立即傳回。除了錯誤的引數之外,任何失敗都會被靜默忽略。

接收對呼叫程序先前使用 send_request/4 發出的 call 請求的回應。

接收對應於儲存在 RequestIdCollection 中的請求識別碼的 call 請求的回應。RequestIdCollection 的所有請求識別碼都必須對應於使用 send_request/4send_request/6 發出的請求,且所有請求都必須由呼叫此函數的程序發出。

儲存 RequestId 並將 Label 與請求識別碼相關聯,方法是將此資訊新增至 RequestIdCollection 並傳回產生的請求識別碼集合。

傳回新的空請求識別碼集合。可以使用請求識別碼集合來處理多個未完成的請求。

傳回儲存在 RequestIdCollection 中的請求識別碼數量。

傳回一個 {RequestId, Label} 元組列表,該列表對應於 RequestIdCollection 集合中存在的所有帶有相關聯標籤的請求識別碼。

將非同步 call 請求發送至節點 Node

將非同步 call 請求發送至節點 NodeLabel 將與操作的請求識別碼相關聯,並新增至傳回的請求識別碼集合 NewRequestIdCollection。稍後可以使用該集合,方法是將該集合作為引數傳遞給 receive_response/3wait_response/3check_response/3,從而取得與集合中請求對應的一個回應。

等同於 erpc:wait_response(RequestId, 0)。也就是說,輪詢呼叫程序先前發出的 call 請求的回應訊息。

等待或輪詢呼叫程序先前使用 send_request/4 發出的 call 請求的回應訊息。

等待或輪詢對應於儲存在 RequestIdCollection 中的請求識別碼的 call 請求的回應。RequestIdCollection 的所有請求識別碼都必須對應於使用 send_request/4send_request/6 發出的請求,且所有請求都必須由呼叫此函數的程序發出。

類型

連結到此類型

caught_call_exception()

檢視原始碼 (未匯出) (自 OTP 23.0 起)
-type caught_call_exception() ::
          {throw, Throw :: term()} |
          {exit, {exception, Reason :: term()}} |
          {error, {exception, Reason :: term(), StackTrace :: [stack_item()]}} |
          {exit, {signal, Reason :: term()}} |
          {error, {erpc, Reason :: term()}}.
連結到此不透明

request_id()

檢視原始碼 (自 OTP 23.0 起)
-opaque request_id()

不透明的請求識別碼。有關更多資訊,請參閱 send_request/4

連結到此不透明

request_id_collection()

檢視原始碼 (自 OTP 23.0 起)
-opaque request_id_collection()

不透明的請求識別碼集合(request_id/0),其中每個請求識別碼都可以與使用者選擇的標籤相關聯。有關更多資訊,請參閱 reqids_new/0

連結到此類型

stack_item()

檢視原始碼 (未匯出) (自 OTP 23.0 起)
-type stack_item() ::
          {Module :: atom(),
           Function :: atom(),
           Arity :: arity() | (Args :: [term()]),
           Location :: [{file, Filename :: string()} | {line, Line :: pos_integer()}]}.
連結到此類型

timeout_time()

檢視原始碼 (自 OTP 23.0 起)
-type timeout_time() :: 0..4294967295 | infinity | {abs, integer()}.

erpc 函數使用的逾時時間。

值可以是

  • 0..4294967295 - 相對於目前時間的逾時時間(以毫秒為單位)。

  • infinity - 無限逾時。也就是說,操作永遠不會逾時。

  • {abs, Timeout} - 以毫秒為單位的絕對 Erlang 單調時間逾時。也就是說,當 erlang:monotonic_time(millisecond) 傳回的值大於或等於 Timeout 時,操作將逾時。不允許 Timeout 指定未來超過 4294967295 毫秒的時間。當您擁有對應於完整請求集合的回應的截止時間時(request_id_collection/0),使用絕對逾時值識別逾時時間特別方便,因為您不必一遍又一遍地重新計算直到截止時間的相對時間。

函數

此函式的連結

call(Node, Fun)

檢視原始碼 (自 OTP 23.0 起)
-spec call(Node, Fun) -> Result when Node :: node(), Fun :: function(), Result :: term().

等同於 call(Node, Fun, infinity)

此函式的連結

call(Node, Fun, Timeout)

檢視原始碼 (自 OTP 23.0 起)
-spec call(Node, Fun, Timeout) -> Result
              when Node :: node(), Fun :: function(), Timeout :: timeout_time(), Result :: term().

等同於 erpc:call(Node, erlang, apply, [Fun,[]], Timeout)

可能會拋出與 call/5 相同的例外,此外,如果 Fun 不是零元函數,則會拋出 {erpc, badarg} error 例外。

此函式的連結

call(Node, Module, Function, Args)

檢視原始碼 (自 OTP 23.0 起)
-spec call(Node, Module, Function, Args) -> Result
              when
                  Node :: node(),
                  Module :: atom(),
                  Function :: atom(),
                  Args :: [term()],
                  Result :: term().

等同於 call(Node, Module, Function, Args, infinity)

此函式的連結

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

檢視原始碼 (自 OTP 23.0 起)
-spec call(Node, Module, Function, Args, Timeout) -> Result
              when
                  Node :: node(),
                  Module :: atom(),
                  Function :: atom(),
                  Args :: [term()],
                  Timeout :: timeout_time(),
                  Result :: term().

在節點 Node 上評估 apply(Module, Function, Args) 並傳回對應的值 ResultTimeout 設定 call 操作完成的最長時間限制。

只有在應用函數成功返回且未拋出任何未捕獲的例外、操作未超時且未發生任何故障時,call() 函數才會返回。在所有其他情況下,都會拋出例外。以下例外(按例外類別列出)目前可能會由 call() 拋出

  • throw - 應用函數呼叫了 throw(Value) 且未捕獲此例外。例外原因 Value 等於傳遞給 throw/1 的參數。

  • exit - 例外原因

    • {exception, ExitReason} - 應用函數呼叫了 exit(ExitReason) 且未捕獲此例外。退出原因 ExitReason 等於傳遞給 exit/1 的參數。

    • {signal, ExitReason} - 應用函數的進程接收到退出信號並因該信號而終止。進程以退出原因 ExitReason 終止。

  • error - 例外原因

    • {exception, ErrorReason, StackTrace} - 在應用函數時發生了導致拋出錯誤例外的執行階段錯誤,且應用函數未捕獲此例外。錯誤原因 ErrorReason 表示發生的錯誤類型。StackTrace 的格式與在 try/catch 結構中捕獲時相同。StackTrace 僅限於應用函數及其呼叫的函數。

    • {erpc, ERpcErrorReason} - erpc 操作失敗。以下 ERpcErrorReason 是最常見的幾種

      • badarg - 如果以下任何一項為真

        • Node 不是一個原子。
        • Module 不是一個原子。
        • Function 不是一個原子。
        • Args 不是一個列表。請注意,該列表在客戶端沒有被驗證為正確的列表。
        • Timeout 無效。
      • noconnection - 與 Node 的連線遺失或無法建立。該函數可能會或可能不會被應用。

      • system_limit - 由於達到某些系統限制,erpc 操作失敗。這通常是因為無法在遠端節點 Node 上建立進程,但也可能是其他原因。

      • timeout - erpc 操作超時。該函數可能會或可能不會被應用。

      • notsup - 遠端節點 Node 不支援此 erpc 操作。

如果 erpc 操作失敗,但不知道該函數是否已/將被應用(即,超時或連線遺失),則如果/當應用函數完成時,呼叫者不會收到任何關於結果的進一步資訊。如果應用函數明確地與呼叫進程通信,那麼此通信當然可能會到達呼叫進程。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是呼叫進程本身、伺服器或新產生的進程。

此函式的連結

cast(Node, Fun)

檢視原始碼 (自 OTP 23.0 起)
-spec cast(Node, Fun) -> ok when Node :: node(), Fun :: function().

等同於 erpc:cast(Node,erlang,apply,[Fun,[]])

如果出現以下情況,cast/2 將會失敗並拋出 {erpc, badarg} error 例外

  • Node 不是一個原子。
  • Fun 不是一個零元函數。
此函式的連結

cast(Node, Module, Function, Args)

檢視原始碼 (自 OTP 23.0 起)
-spec cast(Node, Module, Function, Args) -> ok
              when Node :: node(), Module :: atom(), Function :: atom(), Args :: [term()].

在節點 Node 上評估 apply(Module, Function, Args)。不會將回應傳遞給呼叫程序。cast() 在發送 cast 請求後立即傳回。除了錯誤的引數之外,任何失敗都會被靜默忽略。

如果出現以下情況,cast/4 將會失敗並拋出 {erpc, badarg} error 例外

  • Node 不是一個原子。
  • Module 不是一個原子。
  • Function 不是一個原子。
  • Args 不是一個列表。請注意,該列表在客戶端沒有被驗證為正確的列表。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是伺服器或新產生的進程。

此函式的連結

check_response(Message, RequestId)

檢視原始碼 (自 OTP 23.0 起)
-spec check_response(Message, RequestId) -> {response, Result} | no_response
                        when Message :: term(), RequestId :: request_id(), Result :: term().

檢查訊息是否是對呼叫程序先前使用 send_request/4 發出的 call 請求的回應。

RequestId 應為先前發出的 send_request/4 呼叫所返回的值,且對應的回應不應已被 check_response/2receive_response/2wait_response/2 接收並處理完成。Message 是要檢查的訊息。

如果 Message 與回應不符,則會返回原子 no_response。如果 Message 與回應相符,則 call 操作完成,並返回結果,格式為 {response, Result},其中 Result 對應於應用函數返回的值,或拋出例外。可能拋出的例外與 call/4 可能拋出的例外相同。也就是說,不會拋出 {erpc, timeout} error 例外。如果偵測到無效的 RequestIdcheck_response() 將會失敗並拋出 {erpc, badarg} 例外。

如果 erpc 操作失敗,但不知道該函數是否已/將被應用(即,連線遺失),則如果/當應用函數完成時,呼叫者不會收到任何關於結果的進一步資訊。如果應用函數明確地與呼叫進程通信,那麼此通信當然可能會到達呼叫進程。

此函式的連結

check_response(Message, RequestIdCollection, Delete)

檢視原始碼 (自 OTP 25.0 起)
-spec check_response(Message, RequestIdCollection, Delete) ->
                        {{response, Result}, Label, NewRequestIdCollection} | no_response | no_request
                        when
                            Message :: term(),
                            RequestIdCollection :: request_id_collection(),
                            Delete :: boolean(),
                            Result :: term(),
                            Label :: term(),
                            NewRequestIdCollection :: request_id_collection().

檢查訊息是否是對應於儲存在 RequestIdCollection 中的請求識別碼的 call 請求的回應。RequestIdCollection 的所有請求識別碼都必須對應於使用 send_request/4send_request/6 發出的請求,且所有請求都必須由呼叫此函數的程序發出。

Label 是與回應對應的請求的請求識別碼關聯的標籤。當在 請求識別碼集合加入請求識別碼時,或使用 send_request/6 發送請求時,請求識別碼會與標籤關聯。

check_response/2 相比,與特定請求識別碼關聯的返回結果或與特定請求識別碼關聯的例外將會被包裝在 3 元組中。此元組的第一個元素等於 check_response/2 會產生的值,第二個元素等於與特定請求識別碼關聯的 Label,第三個元素 NewRequestIdCollection 是一個可能修改過的請求識別碼集合。error 例外 {erpc, badarg} 不與任何特定請求識別碼關聯,因此不會被包裝。

如果 RequestIdCollection 為空,則會返回原子 no_request。如果 MessageRequestIdCollection 中的任何請求識別碼不符,則會返回原子 no_response

如果 Delete 等於 true,則在產生的 NewRequestIdCollection 中,與 Label 的關聯將已從 RequestIdCollection 中刪除。如果 Delete 等於 false,則 NewRequestIdCollection 將等於 RequestIdCollection。請注意,刪除關聯並非免費,且包含已處理請求的集合仍然可以被後續對 check_response/3receive_response/3wait_response/3 的呼叫使用。然而,如果沒有刪除已處理的關聯,則上述呼叫將無法偵測到何時沒有更多待處理的請求需要處理,因此您必須以其他方式追蹤此資訊,而不是依賴 no_request 返回。請注意,如果您將僅包含已處理或已放棄請求的關聯的集合傳遞給 check_response/3,它將始終返回 no_response

請注意,回應可能會在 {erpc, badarg} 例外發生時被消耗,如果是這樣,則將永遠遺失。

此函式的連結

multicall(Nodes, Fun)

檢視原始碼 (自 OTP 23.0 起)
-spec multicall(Nodes, Fun) -> Result when Nodes :: [atom()], Fun :: function(), Result :: term().

等同於 multicall(Nodes, Fun, infinity)

此函式的連結

multicall(Nodes, Fun, Timeout)

檢視原始碼 (自 OTP 23.0 起)
-spec multicall(Nodes, Fun, Timeout) -> Result
                   when
                       Nodes :: [atom()], Fun :: function(), Timeout :: timeout_time(), Result :: term().

等同於 erpc:multicall(Nodes, erlang, apply, [Fun,[]], Timeout)

可能拋出與 multicall/5 相同的例外,此外,如果 Fun 不是零元函數,則會拋出 {erpc, badarg} error 例外。

此函式的連結

multicall(Nodes, Module, Function, Args)

檢視原始碼 (自 OTP 23.0 起)
-spec multicall(Nodes, Module, Function, Args) -> Result
                   when
                       Nodes :: [atom()],
                       Module :: atom(),
                       Function :: atom(),
                       Args :: [term()],
                       Result :: [{ok, ReturnValue :: term()} | caught_call_exception()].

等同於 multicall(Nodes, Module, Function, Args, infinity)

此函式的連結

multicall(Nodes, Module, Function, Args, Timeout)

檢視原始碼 (自 OTP 23.0 起)
-spec multicall(Nodes, Module, Function, Args, Timeout) -> Result
                   when
                       Nodes :: [atom()],
                       Module :: atom(),
                       Function :: atom(),
                       Args :: [term()],
                       Timeout :: timeout_time(),
                       Result :: [{ok, ReturnValue :: term()} | caught_call_exception()].

在多個節點上平行執行多個 call 操作。

也就是說,在節點 Nodes 上並行評估 apply(Module, Function, Args)Timeout 設定所有 call 操作完成的上限時間。結果會以列表形式返回,其中每個節點的結果都放置在 Nodes 中節點名稱所在的位置。結果列表中的每個項目格式如下:

  • {ok, Result} - 此特定節點的 call 操作返回 Result

  • {Class, ExceptionReason} - 此特定節點的 call 操作拋出了類別為 Class,例外原因為 ExceptionReason 的例外。這些對應於 call/5 可能拋出的例外。

如果發生以下情況,multicall/5 會失敗並拋出 {erpc, badarg} error 例外:

  • Nodes 不是合適的原子列表。請注意,在發生失敗時,某些請求可能已經發送。也就是說,該函數可能在某些節點上應用,也可能沒有。
  • Module 不是一個原子。
  • Function 不是一個原子。
  • Args 不是一個列表。請注意,該列表在客戶端沒有被驗證為正確的列表。

呼叫 erpc:multicall(Nodes, Module, Function, Args) 等同於呼叫 erpc:multicall(Nodes, Module, Function, Args, infinity)。如果忽略效能和失敗行為,這些呼叫也等同於呼叫以下的 my_multicall(Nodes, Module, Function, Args)multicall() 可以利用選擇性接收最佳化,從而無需從頭開始掃描訊息佇列以尋找匹配的訊息。然而,send_request()/receive_response() 組合無法利用這種最佳化。

my_multicall(Nodes, Module, Function, Args) ->
  ReqIds = lists:map(fun (Node) ->
                       erpc:send_request(Node, Module, Function, Args)
                     end,
                     Nodes),
  lists:map(fun (ReqId) ->
              try
                {ok, erpc:receive_response(ReqId, infinity)}
              catch
                Class:Reason ->
                  {Class, Reason}
              end
            end,
            ReqIds).

如果 erpc 操作失敗,但不知道該函數是否已/將被應用(即,逾時、連線遺失或不正確的 Nodes 列表),則呼叫者不會收到關於已應用函數完成時的結果的任何進一步資訊。如果已應用函數與呼叫程序進行通訊,則此類通訊當然可能會到達呼叫程序。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是呼叫進程本身、伺服器或新產生的進程。

此函式的連結

multicast(Nodes, Fun)

檢視原始碼 (自 OTP 23.0 起)
-spec multicast(Nodes, Fun) -> ok when Nodes :: [node()], Fun :: function().

等同於 erpc:multicast(Nodes,erlang,apply,[Fun,[]])

如果發生以下情況,multicast/2 會失敗並拋出 {erpc, badarg} error 例外:

  • Nodes 不是合適的原子列表。
  • Fun 不是一個零元函數。
此函式的連結

multicast(Nodes, Module, Function, Args)

檢視原始碼 (自 OTP 23.0 起)
-spec multicast(Nodes, Module, Function, Args) -> ok
                   when Nodes :: [node()], Module :: atom(), Function :: atom(), Args :: [term()].

在節點 Nodes 上評估 apply(Module, Function, Args)。不會將回應傳遞給呼叫程序。multicast() 在發送 cast 請求後立即傳回。除了錯誤的引數之外,任何失敗都會被靜默忽略。

如果發生以下情況,multicast/4 會失敗並拋出 {erpc, badarg} error 例外:

  • Nodes 不是合適的原子列表。請注意,在發生失敗時,某些請求可能已經發送。也就是說,該函數可能在某些節點上應用,也可能沒有。
  • Module 不是一個原子。
  • Function 不是一個原子。
  • Args 不是一個列表。請注意,該列表在客戶端沒有被驗證為正確的列表。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是伺服器或新產生的進程。

此函式的連結

receive_response(RequestId)

檢視原始碼 (自 OTP 23.0 起)
-spec receive_response(RequestId) -> Result when RequestId :: request_id(), Result :: term().

等同於 receive_response(RequestId, infinity)

此函式的連結

receive_response(RequestId, Timeout)

檢視原始碼 (自 OTP 23.0 起)
-spec receive_response(RequestId, Timeout) -> Result
                          when RequestId :: request_id(), Timeout :: timeout_time(), Result :: term().

接收對呼叫程序先前使用 send_request/4 發出的 call 請求的回應。

RequestId 應該是先前呼叫 send_request/4 返回的值,並且不應已由 receive_response()check_response/4wait_response/4 接收並完整處理對應的回應。

Timeout 設定等待回應的最長時限。如果操作逾時,則會放棄由 RequestId 識別的請求,然後會拋出 {erpc, timeout} error 例外。也就是說,在逾時後,永遠不會收到對應該請求的回應。如果收到回應,則 call 操作完成,且會返回結果或拋出例外。可能拋出的例外對應於 call/5 可能拋出的相同例外。receive_response/2 在偵測到無效的 RequestId 或傳遞無效的 Timeout 時,會失敗並拋出 {erpc, badarg} 例外。

如果忽略效能,則以下呼叫函式 my_call(Node, Module, Function, Args, Timeout) 等同於呼叫 erpc:call(Node, Module, Function, Args, Timeout)call() 可以利用選擇性接收最佳化,從而無需從頭開始掃描訊息佇列以尋找匹配的訊息。然而,send_request()/receive_response() 組合無法利用這種最佳化。

my_call(Node, Module, Function, Args, Timeout) ->
  RequestId = erpc:send_request(Node, Module, Function, Args),
  erpc:receive_response(RequestId, Timeout).

如果 erpc 操作失敗,但不知道該函數是否已/將被應用(即,逾時或連線遺失),則呼叫者不會收到關於已應用函數完成時的結果的任何進一步資訊。如果已應用函數明確與呼叫程序進行通訊,則此類通訊當然可能會到達呼叫程序。

此函式的連結

receive_response(RequestIdCollection, Timeout, Delete)

檢視原始碼 (自 OTP 25.0 起)
-spec receive_response(RequestIdCollection, Timeout, Delete) ->
                          {Result, Label, NewRequestIdCollection} | no_request
                          when
                              RequestIdCollection :: request_id_collection(),
                              Timeout :: timeout_time(),
                              Delete :: boolean(),
                              Result :: term(),
                              Label :: term(),
                              NewRequestIdCollection :: request_id_collection().

接收對應於儲存在 RequestIdCollection 中的請求識別碼的 call 請求的回應。RequestIdCollection 的所有請求識別碼都必須對應於使用 send_request/4send_request/6 發出的請求,且所有請求都必須由呼叫此函數的程序發出。

Label 是與回應對應的請求的請求識別碼關聯的標籤。當在 請求識別碼集合加入請求識別碼時,或使用 send_request/6 發送請求時,請求識別碼會與標籤關聯。

receive_response/2 相比,與特定請求識別碼關聯的返回結果或與特定請求識別碼關聯的例外將會包裝在 3 元組中。此元組的第一個元素等於 receive_response/2 會產生的值,第二個元素等於與特定請求識別碼關聯的 Label,第三個元素 NewRequestIdCollection 是可能經過修改的請求識別碼集合。error 例外 {erpc, badarg}{erpc, timeout} 不與任何特定請求識別碼關聯,因此不會包裝。

如果 RequestIdCollection 為空,則會返回原子 no_request

如果操作逾時,則會放棄由 RequestIdCollection 識別的所有請求,然後會拋出 {erpc, timeout} error 例外。也就是說,在逾時後,永遠不會收到對應 RequestIdCollection 中任何請求識別碼的回應。receive_response/3wait_response/3 之間的差異在於,receive_response/3 會在逾時時放棄請求,因此會忽略任何潛在的未來回應,而 wait_response/3 則不會。

如果 Delete 等於 true,則在結果 NewRequestIdCollection 中,與 Label 的關聯將會從 RequestIdCollection 中刪除。如果 Delete 等於 false,則 NewRequestIdCollection 將等於 RequestIdCollection。請注意,刪除關聯不是免費的,而且包含已處理請求的集合仍然可以由後續呼叫 receive_response/3check_response/3wait_response/3 使用。然而,如果沒有刪除已處理的關聯,則上述呼叫將無法偵測到何時沒有更多未完成的請求要處理,因此您必須以其他方式追蹤此情況,而不是依賴 no_request 返回。請注意,如果您將只包含已處理或已放棄請求的關聯的集合傳遞給 receive_response/3,則它將始終封鎖,直到觸發由 Timeout 確定的逾時。

請注意,回應可能會在 {erpc, badarg} 例外發生時被消耗,如果是這樣,則將永遠遺失。

此函式的連結

reqids_add(RequestId, Label, RequestIdCollection)

檢視原始碼 (自 OTP 25.0 起)
-spec reqids_add(RequestId :: request_id(),
                 Label :: term(),
                 RequestIdCollection :: request_id_collection()) ->
                    NewRequestIdCollection :: request_id_collection().

儲存 RequestId 並將 Label 與請求識別碼相關聯,方法是將此資訊新增至 RequestIdCollection 並傳回產生的請求識別碼集合。

此函式的連結

reqids_new()

檢視原始碼 (自 OTP 25.0 起)
-spec reqids_new() -> NewRequestIdCollection :: request_id_collection().

傳回新的空請求識別碼集合。可以使用請求識別碼集合來處理多個未完成的請求。

使用 reqids_add/3 可以將由 send_request/4 發出的請求的請求識別碼儲存在請求識別碼集合中。此類請求識別碼集合稍後可用於通過將集合作為引數傳遞給 check_response/3receive_response/3wait_response/3,來獲取集合中對應請求的一個回應。

可以使用 reqids_size/1 來確定請求識別碼集合中的請求識別碼數量。

此函式的連結

reqids_size(RequestIdCollection)

檢視原始碼 (自 OTP 25.0 起)
-spec reqids_size(RequestIdCollection :: request_id_collection()) -> non_neg_integer().

傳回儲存在 RequestIdCollection 中的請求識別碼數量。

此函式的連結

reqids_to_list(RequestIdCollection)

檢視原始碼 (自 OTP 25.0 起)
-spec reqids_to_list(RequestIdCollection :: request_id_collection()) ->
                        [{RequestId :: request_id(), Label :: term()}].

傳回一個 {RequestId, Label} 元組列表,該列表對應於 RequestIdCollection 集合中存在的所有帶有相關聯標籤的請求識別碼。

此函式的連結

send_request(Node, Fun)

檢視原始碼 (自 OTP 23.0 起)
-spec send_request(Node, Fun) -> RequestId
                      when Node :: node(), Fun :: function(), RequestId :: request_id().

等同於 erpc:send_request(Node, erlang, apply, [Fun, []])

如果發生以下情況,會失敗並拋出 {erpc, badarg} error 例外:

  • Node 不是一個原子。
  • Fun 不是零元函數。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是伺服器或新產生的進程。

此函式的連結

send_request/4

檢視原始碼 (自 OTP 23.0 起)
-spec send_request(Node, Module, Function, Args) -> RequestId
                      when
                          Node :: node(),
                          Module :: atom(),
                          Function :: atom(),
                          Args :: [term()],
                          RequestId :: request_id();
                  (Node, Fun, Label, RequestIdCollection) -> NewRequestIdCollection
                      when
                          Node :: node(),
                          Fun :: function(),
                          Label :: term(),
                          RequestIdCollection :: request_id_collection(),
                          NewRequestIdCollection :: request_id_collection().

將非同步 call 請求發送至節點 Node

send_request/4 返回一個請求識別碼,該識別碼稍後會傳遞給 receive_response/2wait_response/2check_response/2,以獲取呼叫請求的回應。除了將請求識別碼直接傳遞給這些函式外,它也可以使用 reqids_add/3 新增到請求識別碼集合中。此類請求識別碼集合稍後可用於通過將集合作為引數傳遞給 receive_response/3wait_response/3check_response/3,來獲取集合中對應請求的一個回應。如果您將要把請求識別碼儲存在請求識別碼集合中,則可能需要考慮改用 send_request/6

如果忽略效能,則以下呼叫函式 my_call(Node, Module, Function, Args, Timeout) 等同於呼叫 erpc:call(Node, Module, Function, Args, Timeout)call() 可以利用選擇性接收最佳化,從而無需從頭開始掃描訊息佇列以尋找匹配的訊息。然而,send_request()/receive_response() 組合無法利用這種最佳化。

my_call(Node, Module, Function, Args, Timeout) ->
  RequestId = erpc:send_request(Node, Module, Function, Args),
  erpc:receive_response(RequestId, Timeout).

如果發生以下情況,會失敗並拋出 {erpc, badarg} error 例外:

  • Node 不是一個原子。
  • Module 不是一個原子。
  • Function 不是一個原子。
  • Args 不是一個列表。請注意,該列表在客戶端沒有被驗證為正確的列表。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是伺服器或新產生的進程。

等同於 erpc:send_request(Node, erlang, apply, [Fun,[]]), Label, RequestIdCollection)

如果發生以下情況,會失敗並拋出 {erpc, badarg} error 例外:

  • Node 不是一個原子。
  • Fun 不是零元函數。
  • 偵測到 RequestIdCollection 不是請求識別碼集合。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是伺服器或新產生的進程。

此函式的連結

send_request(Node, Module, Function, Args, Label, RequestIdCollection)

檢視原始碼 (自 OTP 25.0 起)
-spec send_request(Node, Module, Function, Args, Label, RequestIdCollection) -> NewRequestIdCollection
                      when
                          Node :: node(),
                          Module :: atom(),
                          Function :: atom(),
                          Args :: [term()],
                          Label :: term(),
                          RequestIdCollection :: request_id_collection(),
                          NewRequestIdCollection :: request_id_collection().

將非同步 call 請求發送至節點 NodeLabel 將與操作的請求識別碼相關聯,並新增至傳回的請求識別碼集合 NewRequestIdCollection。稍後可以使用該集合,方法是將該集合作為引數傳遞給 receive_response/3wait_response/3check_response/3,從而取得與集合中請求對應的一個回應。

等同於 erpc:reqids_add(erpc:send_request(Node, Module, Function, Args), Label, RequestIdCollection),但呼叫 send_request/6 效率會稍微高一些。

如果發生以下情況,會失敗並拋出 {erpc, badarg} error 例外:

  • Node 不是一個原子。
  • Module 不是一個原子。
  • Function 不是一個原子。
  • Args 不是一個列表。請注意,該列表在客戶端沒有被驗證為正確的列表。
  • 偵測到 RequestIdCollection 不是請求識別碼集合。

注意

您不能對執行 apply() 的進程做*任何*假設。它可能是伺服器或新產生的進程。

此函式的連結

wait_response(RequestId)

檢視原始碼 (自 OTP 23.0 起)
-spec wait_response(RequestId) -> {response, Result} | no_response
                       when RequestId :: request_id(), Result :: term().

等同於 erpc:wait_response(RequestId, 0)。也就是說,輪詢呼叫程序先前發出的 call 請求的回應訊息。

此函式的連結

wait_response(RequestId, WaitTime)

檢視原始碼 (自 OTP 23.0 起)
-spec wait_response(RequestId, WaitTime) -> {response, Result} | no_response
                       when RequestId :: request_id(), WaitTime :: timeout_time(), Result :: term().

等待或輪詢呼叫程序先前使用 send_request/4 發出的 call 請求的回應訊息。

RequestId 應該是先前呼叫 send_request() 返回的值,且對應的回應不應該已經被 check_response/2receive_response/2wait_response() 接收並處理完成。

WaitTime 設定等待回應的最長時限。如果在 WaitTime 超時觸發前沒有收到任何回應,則會返回原子 no_response。在收到回應並由 check_response()receive_response()wait_response() 完成處理之前,可以根據需要繼續等待回應多次。如果收到回應,則 call 操作完成,且返回結果為 {response, Result},其中 Result 對應於所應用函數返回的值,或者會引發例外。可以引發的例外對應於 call/4 可以引發的相同例外。也就是說,不會引發 {erpc, timeout} error 例外。如果偵測到無效的 RequestId 或傳遞了無效的 WaitTimewait_response/2 將會失敗並引發 {erpc, badarg} 例外。

如果 erpc 操作失敗,但不知道該函數是否已經/將會被應用(也就是說,等待時間值過大,或連接中斷),則呼叫方將不會收到關於所應用函數何時完成的進一步資訊。如果所應用的函數顯式地與呼叫程序通信,則此類通信當然可能會到達呼叫程序。

此函式的連結

wait_response(RequestIdCollection, WaitTime, Delete)

檢視原始碼 (自 OTP 25.0 起)
-spec wait_response(RequestIdCollection, WaitTime, Delete) ->
                       {{response, Result}, Label, NewRequestIdCollection} | no_response | no_request
                       when
                           RequestIdCollection :: request_id_collection(),
                           WaitTime :: timeout_time(),
                           Delete :: boolean(),
                           Label :: term(),
                           NewRequestIdCollection :: request_id_collection(),
                           Result :: term().

等待或輪詢對應於儲存在 RequestIdCollection 中的請求識別碼的 call 請求的回應。RequestIdCollection 的所有請求識別碼都必須對應於使用 send_request/4send_request/6 發出的請求,且所有請求都必須由呼叫此函數的程序發出。

Label 是與回應對應的請求的請求識別碼關聯的標籤。當在 請求識別碼集合加入請求識別碼時,或使用 send_request/6 發送請求時,請求識別碼會與標籤關聯。

wait_response/2 相比,與特定請求標識符相關的返回結果或與特定請求標識符相關的例外將會被封裝在一個 3 元組中。此元組的第一個元素等於 wait_response/2 將會產生的值,第二個元素等於與特定請求標識符相關的 Label,第三個元素 NewRequestIdCollection 是一個可能被修改過的請求標識符集合。error 例外 {erpc, badarg} 不與任何特定請求標識符相關聯,因此不會被封裝。

如果 RequestIdCollection 為空,則會返回 no_request。如果在 WaitTime 超時觸發前沒有收到任何回應,則會返回原子 no_response。在收到回應並由 check_response()receive_response()wait_response() 完成處理之前,可以根據需要繼續等待回應多次。receive_response/3wait_response/3 之間的區別在於,receive_response/3 會在超時時放棄請求,以便忽略任何潛在的未來回應,而 wait_response/3 則不會。

如果 Delete 等於 true,則與 Label 的關聯將會從結果 NewRequestIdCollection 中的 RequestIdCollection 刪除。如果 Delete 等於 false,則 NewRequestIdCollection 將會等於 RequestIdCollection。請注意,刪除關聯並非沒有代價,且包含已處理請求的集合仍然可以被後續呼叫 wait_response/3check_response/3receive_response/3 使用。但是,如果沒有刪除已處理的關聯,則上述呼叫將無法偵測到何時沒有更多待處理的請求要處理,因此您必須以其他方式追蹤此資訊,而不是依賴 no_request 返回值。請注意,如果您將一個僅包含已處理或已放棄請求的關聯集合傳遞給 wait_response/3,它將始終阻塞,直到觸發由 WaitTime 確定的超時,然後返回 no_response

請注意,回應可能會在 {erpc, badarg} 例外發生時被消耗,如果是這樣,則將永遠遺失。