Client Pool
The ClientPool maintains a configurable number of connected ephemeral MixnetClient instances, ready for immediate use. This eliminates the connection latency that comes with creating a new client on each request: the gateway handshake, key generation, and topology fetch all happen ahead of time.
How it works
- Create the pool with a target reserve size:
ClientPool::new(5) - Start the background loop:
pool.start(). It immediately begins connecting clients - Pop a client when needed:
pool.get_mixnet_client()returnsSome(client)orNoneif the pool is empty - Use the client normally: send messages, open streams, etc.
- Disconnect the client when done. The background loop notices the pool is below reserve and creates a replacement
Clients are consumed, not returned. The pool creates new ones to maintain the reserve. If the pool is empty, you can fall back to MixnetClient::connect_new() (slower, but keeps things working).
The NymProxyClient (TcpProxy) uses a ClientPool internally: one client per incoming TCP connection.
Quick example
use nym_sdk::client_pool::ClientPool;
use nym_network_defaults::setup_env;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
nym_bin_common::logging::setup_tracing_logger();
// Load mainnet network defaults into env vars (required by ClientPool)
setup_env(None::<String>);
let pool = ClientPool::new(5); // maintain 5 clients in reserve
let pool_clone = pool.clone();
tokio::spawn(async move { pool_clone.start().await });
// Get a client when needed
if let Some(client) = pool.get_mixnet_client().await {
println!("Got client: {}", client.nym_address());
client.disconnect().await;
}
pool.disconnect_pool().await;
Ok(())
}Further reading
- Tutorial: Handle bursty traffic: step-by-step guide covering pool creation, burst handling, and fallback logic
- API reference on docs.rs (opens in a new tab): type details, method signatures, and architecture docs
- Example source on GitHub (opens in a new tab): complete working example