ZenWebsocket.ClientSupervisor (ZenWebsocket v0.4.2)

Copy Markdown View Source

Optional supervisor for WebSocket client connections.

Provides supervised client connections with automatic restart on failure. Each client runs under its own supervisor for isolation.

Restart Policy

Allows up to 10 restarts within 60 seconds. This prevents rapid restart loops while allowing recovery from transient failures.

Adding to Your Supervision Tree

# In your application supervisor
children = [
  # Start the ClientSupervisor
  ZenWebsocket.ClientSupervisor,
  # Your other children...
]

Supervisor.start_link(children, strategy: :one_for_one)

Usage

# After supervisor is started, create supervised connections
{:ok, client} = ClientSupervisor.start_client("wss://example.com", 
  retry_count: 5,
  heartbeat_config: %{type: :deribit, interval: 30_000}
)

# The client will be automatically restarted on crashes
# with exponential backoff between restarts

API Functions

FunctionArityDescriptionParam Kinds
send_balanced2Send a message using health-based load balancing with failover.message: value, opts: value
stop_client1Gracefully stop a supervised client.pid: value
list_clients0List all supervised client connections.-
start_client2Start a supervised WebSocket client with automatic restart.url_or_config: value, opts: value

Summary

Types

Function that returns a list of client PIDs for load balancing

Callback invoked on client lifecycle events

Functions

Returns a specification to start this module under a supervisor.

Lists all supervised client connections.

Sends a message using health-based load balancing.

Starts a supervised WebSocket client.

Starts the client supervisor.

Gracefully stops a supervised client.

Types

discovery_fun()

@type discovery_fun() :: (-> [pid()])

Function that returns a list of client PIDs for load balancing

lifecycle_callback()

@type lifecycle_callback() :: (pid() -> any())

Callback invoked on client lifecycle events

Functions

child_spec(arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

list_clients()

@spec list_clients() :: [pid()]

Lists all supervised client connections.

send_balanced(message, opts \\ [])

@spec send_balanced(
  binary(),
  keyword()
) :: :ok | {:ok, map()} | {:error, term()}

Sends a message using health-based load balancing.

Selects the healthiest connection from the pool and sends the message. On failure, records the error and attempts failover to the next healthiest connection.

Options

  • :max_attempts - Maximum failover attempts (default: 3)
  • :client_discovery - Function returning list of PIDs (default: list_clients/0)

Examples

:ok = ClientSupervisor.send_balanced(message)
{:ok, response} = ClientSupervisor.send_balanced(rpc_message)
{:error, :no_connections} = ClientSupervisor.send_balanced(message)

# With custom discovery (e.g., distributed with :pg)
:ok = ClientSupervisor.send_balanced(message,
  client_discovery: fn -> :pg.get_members(:ws_pool) end
)

start_client(url_or_config, opts \\ [])

@spec start_client(
  String.t() | ZenWebsocket.Config.t(),
  keyword()
) :: {:ok, ZenWebsocket.Client.t()} | {:error, term()}

Starts a supervised WebSocket client.

The client will be automatically restarted on failure according to the supervisor's restart strategy.

Lifecycle Callbacks

  • :on_connect - Called with the client PID after successful connection. Use to register the client with external registries (:pg, Horde, etc.).
  • :on_disconnect - Called with the client PID when the client terminates. Use to unregister from external registries.

Examples

# Basic usage
{:ok, client} = ClientSupervisor.start_client("wss://example.com")

# With lifecycle callbacks for distributed registry
{:ok, client} = ClientSupervisor.start_client("wss://example.com",
  on_connect: fn pid -> :pg.join(:ws_pool, pid) end,
  on_disconnect: fn pid -> :pg.leave(:ws_pool, pid) end
)

start_link(init_arg)

@spec start_link(term()) :: Supervisor.on_start()

Starts the client supervisor.

stop_client(pid)

@spec stop_client(pid()) :: :ok | {:error, :not_found}

Gracefully stops a supervised client.