use esox_objectpool::{
ObjectPool, QueryableObjectPool, DynamicObjectPool,
PoolConfiguration
};
use std::time::Duration;
use std::thread;
#[derive(Debug, Clone)]
struct Connection {
id: usize,
data: String,
}
impl Connection {
fn new(id: usize) -> Self {
Self {
id,
data: format!("Connection-{}", id),
}
}
}
fn main() {
println!("=== EsoxSolutions.ObjectPool - Advanced Features ===\n");
queryable_pool();
eviction_ttl();
circuit_breaker_demo();
prometheus_export();
complex_objects();
}
fn queryable_pool() {
println!("1. Queryable Pool:");
let connections = vec![
Connection::new(1),
Connection::new(2),
Connection::new(3),
];
let pool = QueryableObjectPool::new(connections, PoolConfiguration::default());
{
let conn = pool.get_object(|c| c.id == 2).unwrap();
println!(" Found: {:?}", *conn);
}
let result = pool.try_get_object(|c| c.id == 99).unwrap();
println!(" Find ID 99: {}", if result.is_some() { "Found" } else { "Not found" });
println!();
}
fn eviction_ttl() {
println!("2. Eviction / TTL:");
let config = PoolConfiguration::new()
.with_ttl(Duration::from_secs(2))
.with_idle_timeout(Duration::from_secs(1));
let pool = ObjectPool::new(vec![1, 2, 3], config);
println!(" Initial available: {}", pool.available_count());
{
let obj = pool.get_object().unwrap();
println!(" Got: {}", *obj);
}
println!(" Available after quick return: {}", pool.available_count());
println!(" Waiting for idle timeout...");
thread::sleep(Duration::from_millis(1100));
let obj = pool.try_get_object().unwrap();
println!(" After timeout: {}", if obj.is_some() { "Got object" } else { "Object expired" });
println!();
}
fn circuit_breaker_demo() {
println!("3. Circuit Breaker:");
let config = PoolConfiguration::new()
.with_circuit_breaker(3, Duration::from_secs(5));
let pool = ObjectPool::new(vec![1], config);
let _obj = pool.get_object().unwrap();
println!(" Attempting to get from empty pool...");
for i in 0..5 {
match pool.try_get_object() {
Ok(Some(_)) => println!(" Attempt {}: Success", i + 1),
Ok(None) => println!(" Attempt {}: Failed", i + 1),
Err(e) => println!(" Attempt {}: Error ({})", i + 1, e),
}
}
println!();
}
fn prometheus_export() {
println!("4. Prometheus Metrics Export:");
let pool = ObjectPool::new(vec![1, 2, 3, 4, 5], PoolConfiguration::default());
{
let _obj1 = pool.get_object().unwrap();
let _obj2 = pool.get_object().unwrap();
let mut tags = std::collections::HashMap::new();
tags.insert("service".to_string(), "example".to_string());
tags.insert("env".to_string(), "dev".to_string());
let prometheus_text = pool.export_metrics_prometheus("example_pool", Some(&tags));
println!("{}", prometheus_text);
}
}
fn complex_objects() {
println!("5. Complex Objects (Dynamic Pool):");
let pool = DynamicObjectPool::new(
|| Connection::new(rand::random()),
PoolConfiguration::new().with_max_pool_size(10),
);
pool.warmup(3).unwrap();
println!(" Warmed up with 3 connections");
{
let conn = pool.get_object().unwrap();
println!(" Using: {:?}", *conn);
}
let health = pool.get_health_status();
println!(" Health - Available: {}, Active: {}",
health.available_objects, health.active_objects);
}
mod rand {
use std::time::{SystemTime, UNIX_EPOCH};
pub fn random() -> usize {
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.subsec_nanos();
nanos as usize
}
}