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 entersidle
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 is600000
.:retry_idle_error
- amount of time RPC client worker should wait before reconnecting after connection failure when in idle state. The default value is1000
.: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 is5000
.: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 is1000
.:timeout_connect
- timeout used when establishing initial TCP socket connection with RPC server. The default value is5000
.: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
Link to this section Functions
call(pool, request, args, timeout \\ :infinity, retry \\ 5, retry_sleep \\ 100)
View SourceSpecs
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 (seeMeshxRpc.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, [...]}}
call!(pool, request, args, timeout \\ :infinity, retry \\ 5, retry_sleep \\ 100)
View SourceSpecs
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!
cast(pool, request, args, timeout \\ :infinity, retry \\ 5, retry_sleep \\ 100)
View SourceSpecs
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
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]}