Provided by: erlang-manpages_25.3.2.8+dfsg-1ubuntu4.4_all bug

NAME

       erpc - Enhanced Remote Procedure Call

DESCRIPTION

       This  module  provide  services similar to Remote Procedure Calls. A remote procedure call is a method to
       call a function on a remote node and collect the answer. It is  used  for  collecting  information  on  a
       remote node, or for running a function with some specific side effects on the remote node.

       This  is  an  enhanced subset of the operations provided by the rpc module. Enhanced in the sense that it
       makes it possible to distinguish between returned value, raised exceptions, and other errors.  erpc  also
       has  better performance and scalability than the original rpc implementation. However, current rpc module
       will utilize erpc in order to also provide these properties when possible.

       In order for an erpc operation to succeed, the remote node also needs to  support  erpc.  Typically  only
       ordinary Erlang nodes as of OTP 23 have erpc support.

       Note  that  it  is  up  to  the  user to ensure that correct code to execute via erpc is available on the
       involved nodes.

DATA TYPES

       request_id()

              An opaque request identifier. For more information see send_request/4.

       request_id_collection()

              An opaque collection of request identifiers (request_id()) where each request  identifier  can  be
              associated with a label chosen by the user. For more information see reqids_new/0.

       timeout_time() = 0..4294967295 | infinity | {abs, integer()}

                0..4294967295:
                  Timeout relative to current time in milliseconds.

                infinity:
                  Infinite timeout. That is, the operation will never time out.

                {abs, Timeout}:
                  An  absolute  Erlang  monotonic time timeout in milliseconds. That is, the operation will time
                  out when erlang:monotonic_time(millisecond) returns a value larger than or equal  to  Timeout.
                  Timeout  is  not  allowed  to  identify  a  time  further  into  the  future  than  4294967295
                  milliseconds. Identifying the timeout using an absolute timeout value is especially handy when
                  you have a  deadline  for  responses  corresponding  to  a  complete  collection  of  requests
                  (request_id_collection())  ,  since you do not have to recalculate the relative time until the
                  deadline over and over again.

EXPORTS

       call(Node, Fun) -> Result

       call(Node, Fun, Timeout) -> Result

              Types:

                 Node = node()
                 Fun = function()
                 Timeout = timeout_time()
                 Result = term()

              The same as calling erpc:call(Node, erlang, apply, [Fun,[]], Timeout).  May  raise  all  the  same
              exceptions as call/5 plus an {erpc, badarg} error exception if Fun is not a fun of zero arity.

              The call erpc:call(Node,Fun) is the same as the call erpc:call(Node,Fun,infinity).

       call(Node, Module, Function, Args) -> Result

       call(Node, Module, Function, Args, Timeout) -> Result

              Types:

                 Node = node()
                 Module = Function = atom()
                 Args = [term()]
                 Timeout = timeout_time()
                 Result = term()

              Evaluates  apply(Module,  Function, Args) on node Node and returns the corresponding value Result.
              Timeout sets an upper time limit for the call operation to complete.

              The call erpc:call(Node, Module, Function, Args) is equivalent to the call erpc:call(Node, Module,
              Function, Args, infinity)

              The call() function only returns if the applied function successfully returned without raising any
              uncaught exceptions, the operation did not time out, and no failures occurred. In all other  cases
              an  exception  is  raised.  The  following exceptions, listed by exception class, can currently be
              raised by call():

                throw:
                  The applied function called throw(Value) and did  not  catch  this  exception.  The  exception
                  reason Value equals the argument passed to throw/1.

                exit:
                  Exception reason:

                  {exception, ExitReason}:
                    The  applied  function  called  exit(ExitReason)  and did not catch this exception. The exit
                    reason ExitReason equals the argument passed to exit/1.

                  {signal, ExitReason}:
                    The process that applied the function received an exit signal and  terminated  due  to  this
                    signal. The process terminated with exit reason ExitReason.

                error:
                  Exception reason:

                  {exception, ErrorReason, StackTrace}:
                    A  runtime  error  occurred which raised an error exception while applying the function, and
                    the applied function did not catch the exception. The error reason ErrorReason indicates the
                    type of error that  occurred.  StackTrace  is  formatted  as  when  caught  in  a  try/catch
                    construct. The StackTrace is limited to the applied function and functions called by it.

                  {erpc, ERpcErrorReason}:
                    The erpc operation failed. The following ERpcErrorReasons are the most common ones:

                    badarg:
                      If any one of these are true:

                      * Node is not an atom.

                      * Module is not an atom.

                      * Function is not an atom.

                      * Args is not a list. Note that the list is not verified to be a proper list at the client
                        side.

                      * Timeout is invalid.

                    noconnection:
                      The  connection  to Node was lost or could not be established. The function may or may not
                      be applied.

                    system_limit:
                      The erpc operation failed due to some system limit being reached. This  typically  due  to
                      failure to create a process on the remote node Node, but can be other things as well.

                    timeout:
                      The erpc operation timed out. The function may or may not be applied.

                    notsup:
                      The remote node Node does not support this erpc operation.

              If  the  erpc  operation  fails,  but it is unknown if the function is/will be applied (that is, a
              timeout or a connection loss), the caller will not  receive  any  further  information  about  the
              result  if/when  the  applied  function completes. If the applied function explicitly communicates
              with the calling process, such communication may, of course, reach the calling process.

          Note:
              You cannot make any assumptions about the process that will perform the apply().  It  may  be  the
              calling process itself, a server, or a freshly spawned process.

       cast(Node, Fun) -> ok

              Types:

                 Node = node()
                 Fun = function()

              The same as calling erpc:cast(Node,erlang,apply,[Fun,[]]).

              cast/2 fails with an {erpc, badarg} error exception if:

                * Node is not an atom.

                * Fun is not a a fun of zero arity.

       cast(Node, Module, Function, Args) -> ok

              Types:

                 Node = node()
                 Module = Function = atom()
                 Args = [term()]

              Evaluates  apply(Module,  Function,  Args)  on  node Node. No response is delivered to the calling
              process. cast() returns immediately after the cast request has been sent. Any failures beside  bad
              arguments are silently ignored.

              cast/4 fails with an {erpc, badarg} error exception if:

                * Node is not an atom.

                * Module is not an atom.

                * Function is not an atom.

                * Args is not a list. Note that the list is not verified to be a proper list at the client side.

          Note:
              You  cannot  make  any  assumptions  about  the process that will perform the apply(). It may be a
              server, or a freshly spawned process.

       check_response(Message, RequestId) ->
                         {response, Result} | no_response

              Types:

                 Message = term()
                 RequestId = request_id()
                 Result = term()

              Check if a message is a response to a call request previously made by the  calling  process  using
              send_request/4.  RequestId  should  be  the value returned from the previously made send_request/4
              call, and the corresponding response  should  not  already  have  been  received  and  handled  to
              completion  by check_response/2, receive_response/2, or wait_response/2. Message is the message to
              check.

              If Message does not correspond to the response, the  atom  no_response  is  returned.  If  Message
              corresponds  to the response, the call operation is completed and either the result is returned as
              {response, Result} where Result corresponds to the value returned from the applied function or  an
              exception  is  raised. The exceptions that can be raised corresponds to the same exceptions as can
              be raised by call/4. That is, no {erpc, timeout} error exception can be  raised.  check_response()
              will fail with an {erpc, badarg} exception if/when an invalid RequestId is detected.

              If  the  erpc  operation  fails,  but it is unknown if the function is/will be applied (that is, a
              connection loss), the caller will not receive any further information about the result if/when the
              applied function completes. If the applied  function  explicitly  communicates  with  the  calling
              process, such communication may, of course, reach the calling process.

       check_response(Message, RequestIdCollection, Delete) ->
                         {{response, Result},
                          Label, NewRequestIdCollection} |
                         no_response | no_request

              Types:

                 Message = term()
                 RequestIdCollection = request_id_collection()
                 Delete = boolean()
                 Result = Label = term()
                 NewRequestIdCollection = request_id_collection()

              Check  if a message is a response to a call request corresponding to a request identifier saved in
              RequestIdCollection. All request identifiers of RequestIdCollection must  correspond  to  requests
              that  have  been made using send_request/4 or send_request/6, and all requests must have been made
              by the process calling this function.

              Label is the label associated with the  request  identifier  of  the  request  that  the  response
              corresponds  to.  A request identifier is associated with a label when adding a request identifier
              in a request identifier collection, or when sending the request using send_request/6.

              Compared to check_response/2, the returned result associated with a specific request identifier or
              an exception associated with a specific request identifier will be wrapped in a 3-tuple. The first
              element of this tuple equals the value that would have  been  produced  by  check_response/2,  the
              second  element  equals  the  Label associated with the specific request identifier, and the third
              element NewRequestIdCollection is a possibly modified request  identifier  collection.  The  error
              exception  {erpc,  badarg}  is not associated with any specific request identifier, and will hence
              not be wrapped.

              If RequestIdCollection is empty, the atom  no_request  will  be  returned.  If  Message  does  not
              correspond  to  any  of  the  request  identifiers in RequestIdCollection, the atom no_response is
              returned.

              If Delete equals true, the association with Label will have been deleted from  RequestIdCollection
              in the resulting NewRequestIdCollection. If Delete equals false, NewRequestIdCollection will equal
              RequestIdCollection.  Note  that  deleting  an  association  is not for free and that a collection
              containing already handled requests can still be used by  subsequent  calls  to  check_response/3,
              receive_response/3, and wait_response/3. However, without deleting handled associations, the above
              calls  will  not  be  able to detect when there are no more outstanding requests to handle, so you
              will have to keep track of this some other way than relying on a no_request return. Note  that  if
              you  pass  a  collection  only containing associations of already handled or abandoned requests to
              check_response/3, it will always return no_response.

              Note that a response might have been consumed uppon an {erpc, badarg} exception and if so, will be
              lost for ever.

       multicall(Nodes, Fun) -> Result

       multicall(Nodes, Fun, Timeout) -> Result

              Types:

                 Nodes = [atom()]
                 Fun = function()
                 Timeout = timeout_time()
                 Result = term()

              The same as calling erpc:multicall(Nodes, erlang, apply, [Fun,[]], Timeout).  May  raise  all  the
              same  exceptions as multicall/5 plus an {erpc, badarg} error exception if Fun is not a fun of zero
              arity.

              The call erpc:multicall(Nodes,Fun) is the same as the call erpc:multicall(Nodes,Fun, infinity).

       multicall(Nodes, Module, Function, Args) -> Result

       multicall(Nodes, Module, Function, Args, Timeout) -> Result

              Types:

                 Nodes = [atom()]
                 Module = Function = atom()
                 Args = [term()]
                 Timeout = timeout_time()
                 Result =
                     [{ok, ReturnValue :: term()} | caught_call_exception()]
                 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()}}
                 stack_item() =
                     {Module :: atom(),
                      Function :: atom(),
                      Arity :: arity() | (Args :: [term()]),
                      Location ::
                          [{file, Filename :: string()} |
                           {line, Line :: integer() >= 1}]}

              Performs multiple call operations in parallel on multiple nodes. That is, evaluates  apply(Module,
              Function,  Args)  on  the  nodes  Nodes in parallel. Timeout sets an upper time limit for all call
              operations to complete. The result is returned as a list where the result from each node is placed
              at the same position as the node name is placed in Nodes. Each  item  in  the  resulting  list  is
              formatted as either:

                {ok, Result}:
                  The call operation for this specific node returned Result.

                {Class, ExceptionReason}:
                  The  call  operation  for this specific node raised an exception of class Class with exception
                  reason ExceptionReason. These correspond to the exceptions that call/5 can raise.

              multicall/5 fails with an {erpc, badarg} error exception if:

                * Nodes is not a proper list of atoms. Note that some requests may already have been  sent  when
                  the failure occurs. That is, the function may or may not be applied on some nodes.

                * Module is not an atom.

                * Function is not an atom.

                * Args is not a list. Note that the list is not verified to be a proper list at the client side.

              The   call   erpc:multicall(Nodes,   Module,   Function,   Args)   is   equivalent   to  the  call
              erpc:multicall(Nodes, Module, Function, Args,  infinity).  These  calls  are  also  equivalent  to
              calling my_multicall(Nodes, Module, Function, Args) below if one disregard performance and failure
              behavior.  multicall() can utilize a selective receive optimization which removes the need to scan
              the  message  queue  from  the  beginning   in   order   to   find   a   matching   message.   The
              send_request()/receive_response() combination can, however, not utilize this optimization.

              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).

              If  an  erpc  operation  fails,  but  it is unknown if the function is/will be applied (that is, a
              timeout, connection loss, or an improper Nodes list), the caller  will  not  receive  any  further
              information  about  the  result  if/when  the  applied function completes. If the applied function
              communicates with the calling process, such  communication  may,  of  course,  reach  the  calling
              process.

          Note:
              You  cannot  make  any  assumptions about the process that will perform the apply(). It may be the
              calling process itself, a server, or a freshly spawned process.

       multicast(Nodes, Fun) -> ok

              Types:

                 Nodes = [node()]
                 Fun = function()

              The same as calling erpc:multicast(Nodes,erlang,apply,[Fun,[]]).

              multicast/2 fails with an {erpc, badarg} error exception if:

                * Nodes is not a proper list of atoms.

                * Fun is not a a fun of zero arity.

       multicast(Nodes, Module, Function, Args) -> ok

              Types:

                 Nodes = [node()]
                 Module = Function = atom()
                 Args = [term()]

              Evaluates apply(Module, Function, Args) on the nodes  Nodes.  No  response  is  delivered  to  the
              calling  process.  multicast()  returns  immediately  after  the cast requests have been sent. Any
              failures beside bad arguments are silently ignored.

              multicast/4 fails with an {erpc, badarg} error exception if:

                * Nodes is not a proper list of atoms. Note that some requests may already have been  sent  when
                  the failure occurs. That is, the function may or may not be applied on some nodes.

                * Module is not an atom.

                * Function is not an atom.

                * Args is not a list. Note that the list is not verified to be a proper list at the client side.

          Note:
              You  cannot  make  any  assumptions  about  the process that will perform the apply(). It may be a
              server, or a freshly spawned process.

       receive_response(RequestId) -> Result

              Types:

                 RequestId = request_id()
                 Result = term()

              The same as calling erpc:receive_response(RequestId, infinity).

       receive_response(RequestId, Timeout) -> Result

              Types:

                 RequestId = request_id()
                 Timeout = timeout_time()
                 Result = term()

              Receive a response to a call request previously made by the calling process using  send_request/4.
              RequestId  should  be  the  value  returned  from the previously made send_request/4 call, and the
              corresponding response should not  already  have  been  received  and  handled  to  completion  by
              receive_response(), check_response/4, or wait_response/4.

              Timeout  sets  an upper time limit on how long to wait for a response. If the operation times out,
              the request identified by RequestId will be abandoned, then an  {erpc,  timeout}  error  exception
              will  be  raised.  That is, no response corresponding to the request will ever be received after a
              timeout. If a response is received, the call operation is  completed  and  either  the  result  is
              returned  or  an  exception  is  raised. The exceptions that can be raised corresponds to the same
              exceptions as can be raised by  call/5.  receive_response/2  will  fail  with  an  {erpc,  badarg}
              exception if/when an invalid RequestId is detected or if an invalid Timeout is passed.

              A  call  to the function my_call(Node, Module, Function, Args, Timeout) below is equivalent to the
              call erpc:call(Node, Module, Function, Args, Timeout) if one disregards  performance.  call()  can
              utilize a selective receive optimization which removes the need to scan the message queue from the
              beginning  in  order to find a matching message. The send_request()/receive_response() combination
              can, however, not utilize this optimization.

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

              If the erpc operation fails, but it is unknown if the function is/will  be  applied  (that  is,  a
              timeout,  or  a  connection  loss),  the caller will not receive any further information about the
              result if/when the applied function completes. If the  applied  function  explicitly  communicates
              with the calling process, such communication may, of course, reach the calling process.

       receive_response(RequestIdCollection, Timeout, Delete) ->
                           {Result, Label, NewRequestIdCollection} |
                           no_request

              Types:

                 RequestIdCollection = request_id_collection()
                 Timeout = timeout_time()
                 Delete = boolean()
                 Result = Label = term()
                 NewRequestIdCollection = request_id_collection()

              Receive   a   response  to  a  call  request  corresponding  to  a  request  identifier  saved  in
              RequestIdCollection. All request identifiers of RequestIdCollection must  correspond  to  requests
              that  have  been made using send_request/4 or send_request/6, and all requests must have been made
              by the process calling this function.

              Label is the label associated with the  request  identifier  of  the  request  that  the  response
              corresponds  to.  A request identifier is associated with a label when adding a request identifier
              in a request identifier collection, or when sending the request using send_request/6.

              Compared to receive_response/2, the returned result associated with a specific request  identifier
              or  an  exception  associated with a specific request identifier will be wrapped in a 3-tuple. The
              first element of this tuple equals the value that would have been produced by  receive_response/2,
              the second element equals the Label associated with the specific request identifier, and the third
              element  NewRequestIdCollection  is  a  possibly modified request identifier collection. The error
              exceptions {erpc, badarg} and {erpc,  timeout}  are  not  associated  with  any  specific  request
              identifiers, and will hence not be wrapped.

              If RequestIdCollection is empty, the atom no_request will be returned.

              If the operation times out, all requests identified by RequestIdCollection will be abandoned, then
              an  {erpc,  timeout} error exception will be raised. That is, no responses corresponding to any of
              the request identifiers in  RequestIdCollection  will  ever  be  received  after  a  timeout.  The
              difference  between receive_response/3 and wait_response/3 is that receive_response/3 abandons the
              requests at timeout so that any potential future responses are ignored, while wait_response/3 does
              not.

              If Delete equals true, the association with Label will have been deleted from  RequestIdCollection
              in the resulting NewRequestIdCollection. If Delete equals false, NewRequestIdCollection will equal
              RequestIdCollection.  Note  that  deleting  an  association  is not for free and that a collection
              containing already handled requests can still be used by subsequent calls  to  receive_response/3,
              check_response/3,  and  wait_response/3. However, without deleting handled associations, the above
              calls will not be able to detect when there are no more outstanding requests  to  handle,  so  you
              will  have  to keep track of this some other way than relying on a no_request return. Note that if
              you pass a collection only containing associations of already handled  or  abandoned  requests  to
              receive_response/3, it will always block until a timeout determined by Timeout is triggered.

              Note that a response might have been consumed uppon an {erpc, badarg} exception and if so, will be
              lost for ever.

       reqids_add(RequestId :: request_id(),
                  Label :: term(),
                  RequestIdCollection :: request_id_collection()) ->
                     NewRequestIdCollection :: request_id_collection()

              Saves  RequestId  and associates a Label with the request identifier by adding this information to
              RequestIdCollection and returning the resulting request identifier collection.

       reqids_new() -> NewRequestIdCollection :: request_id_collection()

              Returns a new empty request identifier collection. A request identifier collection can be utilized
              in order the handle multiple outstanding requests.

              Request identifiers of requests made by send_request/4  can  be  saved  in  a  request  identifier
              collection using reqids_add/3. Such a collection of request identifiers can later be used in order
              to  get  one  response  corresponding  to a request in the collection by passing the collection as
              argument to check_response/3, receive_response/3, and wait_response/3.

              reqids_size/1 can be used to determine the amount of request identifiers in a  request  identifier
              collection.

       reqids_size(RequestIdCollection :: request_id_collection()) ->
                      integer() >= 0

              Returns the amount of request identifiers saved in RequestIdCollection.

       reqids_to_list(RequestIdCollection :: request_id_collection()) ->
                         [{RequestId :: request_id(), Label :: term()}]

              Returns  a  list  of  {RequestId,  Label} tuples which corresponds to all request identifiers with
              their associated labels present in the RequestIdCollection collection.

       send_request(Node, Fun) -> RequestId

              Types:

                 Node = node()
                 Fun = function()
                 RequestId = request_id()

              The same as calling erpc:send_request(Node, erlang, apply, [Fun, []]).

              Fails with an {erpc, badarg} error exception if:

                * Node is not an atom.

                * Fun is not a fun of zero arity.

          Note:
              You cannot make any assumptions about the process that will perform  the  apply().  It  may  be  a
              server, or a freshly spawned process.

       send_request(Node, Module, Function, Args) -> RequestId

              Types:

                 Node = node()
                 Module = Function = atom()
                 Args = [term()]
                 RequestId = request_id()

              Send  an  asynchronous  call request to the node Node. send_request/4 returns a request identifier
              that later is to be passed to either receive_response/2, wait_response/2, or, check_response/2  in
              order  to get the response of the call request. Besides passing the request identifier directly to
              these functions, it can also be added in a request identifier collection using reqids_add/3.  Such
              a  collection  of request identifiers can later be used in order to get one response corresponding
              to a request in the collection by  passing  the  collection  as  argument  to  receive_response/3,
              wait_response/3,  or,  check_response/3.  If  you  are  about  to save the request identifier in a
              request identifier collection, you may want to consider using send_request/6 instead.

              A call to the function my_call(Node, Module, Function, Args, Timeout) below is equivalent  to  the
              call  erpc:call(Node,  Module,  Function, Args, Timeout) if one disregards performance. call() can
              utilize a selective receive optimization which removes the need to scan the message queue from the
              beginning in order to find a matching message. The  send_request()/receive_response()  combination
              can, however, not utilize this optimization.

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

              Fails with an {erpc, badarg} error exception if:

                * Node is not an atom.

                * Module is not an atom.

                * Function is not an atom.

                * Args is not a list. Note that the list is not verified to be a proper list at the client side.

          Note:
              You  cannot  make  any  assumptions  about  the process that will perform the apply(). It may be a
              server, or a freshly spawned process.

       send_request(Node, Fun, Label, RequestIdCollection) ->
                       NewRequestIdCollection

              Types:

                 Node = node()
                 Fun = function()
                 Label = term()
                 RequestIdCollection = NewRequestIdCollection = request_id_collection()

              The same as calling erpc:send_request(Node, erlang, apply, [Fun,[]]), Label, RequestIdCollection).

              Fails with an {erpc, badarg} error exception if:

                * Node is not an atom.

                * Fun is not a fun of zero arity.

                * RequestIdCollection is detected not to be request identifier collection.

          Note:
              You cannot make any assumptions about the process that will perform  the  apply().  It  may  be  a
              server, or a freshly spawned process.

       send_request(Node, Module, Function, Args, Label,
                    RequestIdCollection) ->
                       NewRequestIdCollection

              Types:

                 Node = node()
                 Module = Function = atom()
                 Args = [term()]
                 Label = term()
                 RequestIdCollection = NewRequestIdCollection = request_id_collection()

              Send  an asynchronous call request to the node Node. The Label will be associated with the request
              identifier  of  the  operation  and  added  to  the   returned   request   identifier   collection
              NewRequestIdCollection.   The  collection  can  later  be  used  in  order  to  get  one  response
              corresponding  to  a  request  in  the  collection  by  passing  the  collection  as  argument  to
              receive_response/3, wait_response/3, or, check_response/3.

              The  same  as  calling  erpc:reqids_add(erpc:send_request(Node,  Module,  Function,  Args), Label,
              RequestIdCollection), but calling send_request/6 is slightly more efficient.

              Fails with an {erpc, badarg} error exception if:

                * Node is not an atom.

                * Module is not an atom.

                * Function is not an atom.

                * Args is not a list. Note that the list is not verified to be a proper list at the client side.

                * RequestIdCollection is detected not to be request identifier collection.

          Note:
              You cannot make any assumptions about the process that will perform  the  apply().  It  may  be  a
              server, or a freshly spawned process.

       wait_response(RequestId) -> {response, Result} | no_response

              Types:

                 RequestId = request_id()
                 Result = term()

              The  same  as  calling erpc:wait_response(RequestId, 0). That is, poll for a response message to a
              call request previously made by the calling process.

       wait_response(RequestId, WaitTime) ->
                        {response, Result} | no_response

              Types:

                 RequestId = request_id()
                 WaitTime = timeout_time()
                 Result = term()

              Wait or poll for a response message to a call request previously made by the calling process using
              send_request/4. RequestId should be the value returned from  the  previously  made  send_request()
              call,  and  the  corresponding  response  should  not  already  have  been received and handled to
              completion by check_response/2, receive_response/2, or wait_response().

              WaitTime sets an upper time limit on how long to wait for a response. If no response  is  received
              before  the  WaitTime  timeout  has  triggered,  the  atom no_response is returned. It is valid to
              continue waiting for a response as many times as needed up until a response has been received  and
              completed  by check_response(), receive_response(), or wait_response(). If a response is received,
              the call operation is completed and either the result is  returned  as  {response,  Result}  where
              Result  corresponds to the value returned from the applied function or an exception is raised. The
              exceptions that can be raised corresponds to the same exceptions as can be raised by call/4.  That
              is,  no  {erpc,  timeout}  error exception can be raised. wait_response/2 will fail with an {erpc,
              badarg} exception if/when an invalid RequestId is detected or if an invalid WaitTime is passed.

              If the erpc operation fails, but it is unknown if the function is/will be applied (that is, a  too
              large  wait time value, or a connection loss), the caller will not receive any further information
              about the result if/when the applied  function  completes.  If  the  applied  function  explicitly
              communicates  with  the  calling  process,  such  communication  may, of course, reach the calling
              process.

       wait_response(RequestIdCollection, WaitTime, Delete) ->
                        {{response, Result},
                         Label, NewRequestIdCollection} |
                        no_response | no_request

              Types:

                 RequestIdCollection = request_id_collection()
                 WaitTime = timeout_time()
                 Delete = boolean()
                 Label = term()
                 NewRequestIdCollection = request_id_collection()
                 Result = term()

              Wait or poll for a response to a call request corresponding  to  a  request  identifier  saved  in
              RequestIdCollection.  All  request  identifiers of RequestIdCollection must correspond to requests
              that have been made using send_request/4 or send_request/6, and all requests must have  been  made
              by the process calling this function.

              Label  is  the  label  associated  with  the  request  identifier of the request that the response
              corresponds to. A request identifier is associated with a label when adding a  request  identifier
              in a request identifier collection, or when sending the request using send_request/6.

              Compared  to wait_response/2, the returned result associated with a specific request identifier or
              an exception associated with a specific request identifier will be wrapped in a 3-tuple. The first
              element of this tuple equals the value that would  have  been  produced  by  wait_response/2,  the
              second  element  equals  the  Label associated with the specific request identifier, and the third
              element NewRequestIdCollection is a possibly modified request  identifier  collection.  The  error
              exception  {erpc,  badarg}  is not associated with any specific request identifier, and will hence
              not be wrapped.

              If RequestIdCollection is empty, no_request will be returned. If no response  is  received  before
              the  WaitTime  timeout  has  triggered,  the atom no_response is returned. It is valid to continue
              waiting for a response as many times as needed up until a response has been received and completed
              by   check_response(),   receive_response(),   or   wait_response().   The   difference    between
              receive_response/3  and wait_response/3 is that receive_response/3 abandons requests at timeout so
              that any potential future responses are ignored, while wait_response/3 does not.

              If Delete equals true, the association with Label will have been deleted from  RequestIdCollection
              in the resulting NewRequestIdCollection. If Delete equals false, NewRequestIdCollection will equal
              RequestIdCollection.  Note  that  deleting  an  association  is not for free and that a collection
              containing already handled requests can still be used  by  subsequent  calls  to  wait_response/3,
              check_response/3,  and  receive_response/3.  However,  without  deleting handled associations, the
              above calls will not be able to detect when there are no more outstanding requests to  handle,  so
              you  will have to keep track of this some other way than relying on a no_request return. Note that
              if you pass a collection only containing associations of already handled or abandoned requests  to
              wait_response/3, it will always block until a timeout determined by WaitTime is triggered and then
              return no_response.

              Note that a response might have been consumed uppon an {erpc, badarg} exception and if so, will be
              lost for ever.

Ericsson AB                                      kernel 8.5.4.2                                       erpc(3erl)