MeshxRpc.Client.Pool (MeshxRpc v0.1.0) View Source

RPC client workers pool.

Configuration

RPC client pool is configured with opts argument in child_spec/2 function. Configuration options common to both RPC client and server are described in MeshxRpc "Common configuration" section.

Configuration options specific to RPC client opts argument in child_spec/2:

  • :idle_reconnect - after RPC client-server connection is established or after RPC request processing, client worker enters idle state waiting for the next user request. :idle_reconnect specifies amount of idle time after which client should reestablish connection. One can think about this feature as high level TCP keep-alive/heartbeat action. The default value is 600000.

  • :retry_idle_error - amount of time RPC client worker should wait before reconnecting after connection failure when in idle state. The default value is 1000.

  • :retry_hsk_fail - amount of time RPC client worker should wait before reconnecting after handshake failure. Most common handshake failure reason probably will be inconsistent client/server configuration, for example different :shared_key option on client and server. The default value is 5000.

  • :retry_proxy_fail - amount of time RPC client worker should wait before retrying reconnect to :address after initial socket connection failure. If :address points to mesh upstream endpoint proxy address, failures here can be associated with proxy binary problem. The default value is 1000.

  • :timeout_connect - timeout used when establishing initial TCP socket connection with RPC server. The default value is 5000.

  • :exec_retry_on_error - list of request processing errors on which request execution should be retried. The default value is [:closed, :tcp_closed].

Values for options prefixed with :retry- and :idle_reconnect are randomized by +/-10%. Unit for time related options is millisecond.

Link to this section Summary

Functions

Makes a synchronous RPC call request using workers pool and waits for reply.

Sends an asynchronous RPC cast request using workers pool.

Returns a specification to start a RPC client workers pool under a supervisor.

Link to this section Functions

Link to this function

call(pool, request, args, timeout \\ :infinity, retry \\ 5, retry_sleep \\ 100)

View Source

Specs

call(
  pool :: atom(),
  request :: atom(),
  args :: list(),
  timeout :: timeout(),
  retry :: pos_integer(),
  retry_sleep :: non_neg_integer()
) :: term() | {:error_rpc, reason :: term()}

Makes a synchronous RPC call request using workers pool and waits for reply.

If successful, call/6 returns Kernel.apply(RpcServerMod, request, args) evaluation result on remote server.

If error occurs during request processing {:error_rpc, reason} is returned.

User defined RPC server functions should not return results as tuples with first tuple element being :error_rpc or any atom name starting with :error_rpc (for example :error_rpc_remote) as those tuples are reserved by MeshxRpc internally for error reporting and processing.

Possible request processing errors:

  • :full - all client pool workers are busy and pool manager cannot checkout new worker,
  • :killed - process executing request on remote server was killed because function execution time exceeded allowed timeout (see MeshxRpc.Server.Pool option :timeout_execute),
  • :invalid_cks - checksum check with user provided checksum function (:cks_mfa option) failed,
  • :timeout_cks - checksum calculation timeout,
  • :closed - client worker received user request before handshake with server was completed,
  • :tcp_closed - TCP socket connection was closed,
  • :invalid_ref - request message failed referential integrity check,
  • {:undef, [...]} - request function not defined on server,
  • :invalid_state - server or client worker encountered inconsistent critical state,
  • any :inet POSIX Error Codes,
  • any errors from (de)serialization function.

If remote server does not respond within time specified by timeout argument, process executing RPC call is killed, the function call fails and the caller exits. Additionally connection to remote server is closed which kills corresponding RPC call process being executed on the server. Please be aware of MeshxRpc.Server.Pool :timeout_execute configuration option playing similar role to timeout function argument on the server side.

If error occurs during request processing and error reason is in list defined by :exec_retry_on_error configuration option, request will be retried retry times with randomized exponential back-off starting with retry_sleep msec.

Example:

iex(1)> MeshxRpc.Client.Pool.call(Example1.Client, :echo, "hello world")
"hello world"
iex(2)> MeshxRpc.Client.Pool.call(Example1.Client, :not_existing, "hello world")
{:error_rpc, {:undef,  [...]}}
Link to this function

call!(pool, request, args, timeout \\ :infinity, retry \\ 5, retry_sleep \\ 100)

View Source

Specs

call!(
  pool :: atom(),
  request :: atom(),
  args :: list(),
  timeout :: timeout(),
  retry :: pos_integer(),
  retry_sleep :: non_neg_integer()
) :: term() | {:error_rpc, reason :: term()}

Same as call/6, will reraise remote exception locally.

Example:

iex(1)> MeshxRpc.Client.Pool.call(Example1.Client, :raise_test, "raise kaboom!")
{:error_rpc, %RuntimeError{message: "raise kaboom!"}}
iex(2)> MeshxRpc.Client.Pool.call!(Example1.Client, :raise_test, "raise kaboom!")
** (RuntimeError) raise kaboom!
Link to this function

cast(pool, request, args, timeout \\ :infinity, retry \\ 5, retry_sleep \\ 100)

View Source

Specs

cast(
  pool :: atom(),
  request :: atom(),
  args :: list(),
  timeout :: timeout(),
  retry :: pos_integer(),
  retry_sleep :: non_neg_integer()
) :: :ok

Sends an asynchronous RPC cast request using workers pool.

Function always immediately returns :ok, even if pool doesn't exist or any other error takes place.

args, timeout, retry and retry_sleep function arguments have the same meaning as in case of call/6.

Example:

iex(1)> MeshxRpc.Client.Pool.cast(NotExisting, :undefined, [])
:ok
Link to this function

child_spec(id, opts \\ [])

View Source

Specs

child_spec(id :: atom() | String.t(), opts :: Keyword.t()) ::
  :supervisor.child_spec()

Returns a specification to start a RPC client workers pool under a supervisor.

id is a pool id which might be a name of a module implementing user RPC functions.

opts are options described in "Configuration" section above and in MeshxRpc "Common configuration" section.

Example:

iex(1)> MeshxRpc.Client.Pool.child_spec(Example1.Client, address: {:uds, "/tmp/meshx.sock"})
{Example1.Client,
 {:poolboy, :start_link,
  [
    [
      name: {:local, Example1.Client},
      worker_module: MeshxRpc.Client.Worker
    ],
    [
      ...
    ]
  ]}, :permanent, 5000, :worker, [:poolboy]}
Link to this function

retry_request(pool, req_type, request, args, timeout, retry, retry_sleep, retries \\ 0)

View Source