# Module Rpc_proxy.ManagedSet

    module ManagedSet: sig .. end

Manages a set of clients

    type mset

a managed set

    type mset_policy = [ `Balance_load | `Failover ]

Sets in which order managed clients are picked from the `services` array passed to `create_mset`:

- ``Failover`: Picks an element from the first service in `services` that is enabled and has free capacity. That means that the first service is preferred until it is maxed out or it fails, then the second service is preferred, and so on.
- ``Balance_load`: Picks an element from the service in `services` that is enabled and has the lowest load.

`type ``mset_config = {`

`` | `mset_mclient_config : `Rpc_proxy.ManagedClient.mclient_config`;` | `(*` | The mclient config | `*)`
`` | `mset_policy : `mset_policy`;` | `(*` | The policy | `*)`
`` | `mset_pending_calls_max : `int`;` | `(*` | When an mclient processes this number of calls at the same time, it is considered as fully busy. (Value must by > 0). | `*)`
`` | `mset_pending_calls_norm : `int`;` | `(*` | When an mclient processes less than this number of calls, its load is considered as too light, and it is tried to put more load on this client before opening another one | `*)`
`` | `mset_idempotent_max : `int`;` | `(*` | How often idempotent procedures may be tried to be called. A negative value means infinite. | `*)`
`` | `mset_idempotent_wait : `float`;` | `(*` | Wait this number of seconds before trying again | `*)`

}

    exception Cluster_service_unavailable

Raised by `mset_pick` when no available endpoint can be found, or all available endpoints have reached their maximum load.

    val create_mset_config : ?mclient_config:Rpc_proxy.ManagedClient.mclient_config ->
           ?policy:mset_policy ->
           ?pending_calls_max:int ->
           ?pending_calls_norm:int ->
           ?idempotent_max:int ->
           ?idempotent_wait:float -> unit -> mset_config

Create a config record. The optional arguments set the config components with the same name. The defaults are:

- `mclient_config`: The default mclient config
- `policy`: ``Balance_load`
- `pending_calls_max`: `max_int`
- `pending_calls_norm`: 1
- `idempotent_max`: 3
- `idempotent_wait`: 5.0

    val create_mset : mset_config ->
           (Rpc_client.connector * int) array ->
           Unixqueue.event_system -> mset

`create_mset config services`: The mset is created with `config`, and the `services` array describes which ports are available, and how often each port may be contacted (i.e. max number of connections).

    val mset_pick : ?from:int list ->
           mset -> Rpc_proxy.ManagedClient.mclient * int

Pick an mclient for another call, or raise `Cluster_service_unavailable`. The returned int is the index in the `mset_services` array.

If `from` is given, not all specified mclients qualify for this call. In `from` one can pass a list of indexes pointing into the `mset_services` array, and only from these mclients the mclient is picked. For ``Failover` policies, the order given in `from` is respected, and the mclients are checked from left to right.

    val mset_services : mset -> (Rpc_client.connector * int) array

Returns the service array

    val mset_load : mset -> int array

Returns the number of pending calls per service

    val event_system : mset -> Unixqueue.event_system

Return the event system

    val shut_down : mset -> unit

    val sync_shutdown : mset -> unit

    val trigger_shutdown : mset -> (unit -> unit) -> unit

Shut down the managed set. See the corresponding functions `Rpc_client.shut_down`, `Rpc_client.sync_shutdown`, and `Rpc_client.trigger_shutdown`

    val idempotent_async_call : ?from:int list ->
           mset ->
           (Rpc_proxy.ManagedClient.mclient -> 'a -> ((unit -> 'b) -> unit) -> unit) ->
           'a -> ((unit -> 'b) -> unit) -> unit

`idempotent_async_call mset async_call arg emit`: Picks a new `mclient` and calls `async_call mclient arg emit`. If the call leads to a fatal error, a new `mclient` is picked, and the call is repeated. In total, the call may be tried `mset_idempotent_max` times. It is recommended to set `rcache_threshold` to 1 when using this function because this enforces that a different mclient is picked when the first one fails.

Note that a timeout is not considered as a fatal error by default; one has to enable that by setting `mclient_msg_timeout_is_fatal`.

Note that this form of function is compatible with the generated `foo'async` functions of the language mapping.

`from` has the same meaning as in `mset_pick`.

    val idempotent_sync_call : ?from:int list ->
           mset ->
           (Rpc_proxy.ManagedClient.mclient -> 'a -> ((unit -> 'b) -> unit) -> unit) ->
           'a -> 'b

Synchronized version. Note that you have to pass an asynchronous function as second argument. The result is synchronous, however.