connection-pool 0.3.8

A high-performance, generic async connection pool for Rust with background cleanup and comprehensive logging
Documentation
# Connection Pool


A flexible, high-performance, generic async connection pool for Rust with background cleanup and comprehensive logging.

[![Crates.io](https://img.shields.io/crates/v/connection-pool.svg)](https://crates.io/crates/connection-pool)
[![Documentation](https://docs.rs/connection-pool/badge.svg)](https://docs.rs/connection-pool)
[![License](https://img.shields.io/crates/l/connection-pool.svg)](LICENSE)

## โœจ Features


- ๐Ÿš€ **High Performance**: Background cleanup eliminates connection acquisition latency
- ๐Ÿ”ง **Fully Generic**: Support for any connection type (TCP, Database, HTTP, etc.)
- โšก **Async/Await Native**: Built on tokio with modern async Rust patterns
- ๐Ÿ›ก๏ธ **Thread Safe**: Concurrent connection sharing with proper synchronization
- ๐Ÿงน **Smart Cleanup**: Configurable background task for expired connection removal
- ๐Ÿ“Š **Rich Logging**: Comprehensive observability with configurable log levels
- ๐Ÿ”„ **Auto-Return**: RAII-based automatic connection return to pool
- โฑ๏ธ **Timeout Control**: Configurable timeouts for connection creation
- ๐ŸŽฏ **Type Safe**: Compile-time guarantees with zero-cost abstractions
- ๐Ÿงฉ **Extensible**: Custom connection types and validation logic via the `ConnectionManager` trait
- ๐ŸŒ **Versatile**: Suitable for TCP, database, and any custom connection pooling

## Quick Start


Add `connection-pool` to your `Cargo.toml`:

```toml
[dependencies]
connection-pool = "0.2"
tokio = { version = "1.47", features = ["full"] }
```
Then you can use the connection pool in your application:

```rust,no_run
// 1. Define your ConnectionManager
use connection_pool::{ConnectionManager, ConnectionPool};
use std::future::Future;
use std::pin::Pin;
use tokio::net::TcpStream;

#[derive(Clone)]

pub struct TcpConnectionManager {
    pub address: std::net::SocketAddr,
}

impl ConnectionManager for TcpConnectionManager {
    type Connection = TcpStream;
    type Error = std::io::Error;
    type CreateFut = Pin<Box<dyn Future<Output = Result<TcpStream, Self::Error>> + Send>>;
    type ValidFut<'a> = Pin<Box<dyn Future<Output = bool> + Send + 'a>>;

    fn create_connection(&self) -> Self::CreateFut {
        let addr = self.address;
        Box::pin(async move { TcpStream::connect(addr).await })
    }

    fn is_valid<'a>(&'a self, conn: &'a mut Self::Connection) -> Self::ValidFut<'a> {
        Box::pin(async move {
            // Lightweight socket check only; for real liveness use a protocol heartbeat.
            conn.peer_addr().is_ok()
        })
    }
}

#[tokio::main]

async fn main() -> std::io::Result<()> {
    // 2. Create a connection pool
    let manager = TcpConnectionManager { address: "127.0.0.1:8080".parse().unwrap() };
    let pool = ConnectionPool::new(
        Some(10), // max pool size
        None,     // default idle timeout
        None,     // default connection timeout
        None,     // default cleanup config
        manager,
    );

    // 3. Acquire and use a connection
    let mut conn = pool.clone().get_connection().await.unwrap();
    use tokio::io::AsyncWriteExt;
    conn.write_all(b"hello").await.unwrap();
    Ok(())
}
```

`peer_addr()` is only a cheap socket-level check. It can tell you whether the
stream still exists locally, but it does not prove that the remote service is
actually healthy or ready to speak your protocol.

If you need stronger validation, add an application-level heartbeat such as
`ping`/`pong`, and make `is_valid` send and verify that message instead of
touching the data stream with a read.

## Advanced Usage

- You can pool any connection type (e.g. database, API client) by implementing the `ConnectionManager` trait.
- For TCP, prefer a protocol-level health check when you need to prove the peer is responsive.
- See `examples/db_example.rs` for a custom type example.

## Testing

```bash
cargo test
```

## ๐ŸŽ›๏ธ Configuration Options


| Parameter | Description | Default |
|-----------|-------------|---------|
| `max_size` | Maximum number of connections | 10 |
| `max_idle_time` | Connection idle timeout | 5 minutes |
| `connection_timeout` | Connection creation timeout | 10 seconds |
| `cleanup_interval` | Background cleanup interval | 30 seconds |

## ๐Ÿ—๏ธ Architecture



The connection pool is now based on a single `ConnectionManager` abstraction:

```text
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           ConnectionPool<M: Manager>         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ€ข Holds a user-defined ConnectionManager    โ”‚
โ”‚  โ€ข Manages a queue of pooled connections     โ”‚
โ”‚  โ€ข Semaphore for max concurrent connections  โ”‚
โ”‚  โ€ข Background cleanup for idle connections   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ”‚
      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
      โ”‚                   โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Semaphore โ”‚   โ”‚ Background Task  โ”‚
โ”‚ (Limits   โ”‚   โ”‚ (Cleans up idle  โ”‚
โ”‚  max conn)โ”‚   โ”‚  connections)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Connection Queue โ”‚
โ”‚ (VecDeque)       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  PooledStream    โ”‚
โ”‚  (RAII wrapper   โ”‚
โ”‚   auto-returns)  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

### Key Components


- **Semaphore**: Controls maximum concurrent connections
- **Background Cleanup**: Async task for removing expired connections  
- **Connection Queue**: FIFO queue of available connections
- **RAII Wrapper**: `PooledStream` for automatic connection return

## ๐Ÿงช Testing


Run the examples to see the pool in action:

```bash
# Basic TCP example

cargo run --example echo_example

# Database connection example  

cargo run --example db_example

# Background cleanup demonstration

cargo run --example background_cleanup_example
```

## ๐Ÿค Contributing


Contributions are welcome! Please feel free to submit a Pull Request.

## ๐Ÿ“„ License


This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## ๐Ÿ”— Links


- [Documentation]https://docs.rs/connection-pool
- [Crates.io]https://crates.io/crates/connection-pool
- [Repository]https://github.com/ssrlive/connection-pool