pool #
Connection Pool Module
This module provides a robust connection pooling implementation for managing reusable resources like database connections. It handles connection lifecycle, validation, and efficient resource allocation with minimal overhead.
Features
- Connection Reuse: Efficiently manages reusable connections
- Health Validation: Automatic connection validation
- Dynamic Scaling: Adjusts pool size based on demand
- Intelligent Eviction: Removes stale connections with priority-based cleanup
- Statistics Tracking: Provides detailed pool metrics
- Thread Safety: Fully concurrent-safe implementation
- Graceful Shutdown: Clean resource termination
- Dynamic Configuration: Runtime configuration updates
Connections can be acquired and returned while other threads read statistics or update the configuration, including on Windows. Call close() after these threads finish to stop the pool's background maintenance thread.
Basic Usage
Creating a Pool
import db.mysql
import pool
import time
// Define your connection factory function
fn create_conn() !&pool.ConnectionPoolable {
config := mysql.Config{
host: '127.0.0.1'
port: 3306
username: 'root'
password: '12345678'
dbname: 'mysql'
}
db := mysql.connect(config)!
return &db
}
// Configure pool parameters
config := pool.ConnectionPoolConfig{
max_conns: 50
min_idle_conns: 5
max_lifetime: 2 * time.hour
idle_timeout: 30 * time.minute
get_timeout: 5 * time.second
}
// Create connection pool
mut my_pool := pool.new_connection_pool(create_conn, config)!
// Acquire connection
mut conn := my_pool.get()!
// Convert `conn` to a `mysql.DB` object
mut db := conn as mysql.DB
// Use connection `db`
// ... your operations ...
// db.exec()
// Return connection to pool
my_pool.put(conn)!
// When application exits
my_pool.close()
Configuration Options
| Parameter | Default Value | Description |
|---|---|---|
max_conns |
20 | Maximum connections in pool |
min_idle_conns |
5 | Minimum idle connections to maintain |
max_lifetime |
1 hour | Max connection lifetime |
idle_timeout |
30 minutes | Idle connection timeout |
get_timeout |
5 seconds | Connection acquisition timeout |
retry_base_delay |
1 second | Base delay for connection retries |
max_retry_delay |
30 seconds | Maximum retry delay |
max_retry_attempts |
5 | Maximum connection creation attempts |
Advanced Features
Dynamic Configuration Update
new_config := pool.ConnectionPoolConfig{
max_conns: 100
min_idle_conns: 10
// ... other parameters ...
}
my_pool.update_config(new_config)!
Connection Recovery Signal
// After connection maintenance/outage
my_pool.signal_recovery_event()
Statistics Monitoring
stats := my_pool.stats()
println("Active connections: ${stats.active_conns}")
println("Idle connections: ${stats.idle_conns}")
println("Waiting clients: ${stats.waiting_clients}")
Implementation Notes
- Exponential Backoff: Connection creation uses exponential backoff with jitter
- Priority Eviction: Four priority levels for connection cleanup:
low: Routine maintenancemedium: Connection acquisition failurehigh: Configuration changesurgent: Connection recovery events
- Adaptive Cleanup: Maintenance thread dynamically adjusts processing frequency
- Wait Queue: Fair connection allocation to waiting clients
- Atomic Operations: Non-blocking statistics tracking
Performance Considerations
- Use appropriate
min_idle_connsto balance startup time and memory - Set
max_lifetimeaccording to your backend connection limits - Monitor
creation_errorsstatistic to detect connection issues - Use
evicted_countto identify connection health problems
Example Implementation
// ConnectionPoolable connection interface implementation
struct MyConnection {
// Your connection state
}
fn (mut c MyConnection) validate() !bool {
// Connection health check logic
return true
}
fn (mut c MyConnection) close() ! {
// Physical close logic
}
fn (mut c MyConnection) reset() ! {
// Reset connection to initial state
}
fn new_connection_pool #
fn new_connection_pool(conn_factory fn () !&ConnectionPoolable, config ConnectionPoolConfig) !&ConnectionPool
new_connection_pool creates a new connection pool
interface ConnectionPoolable #
interface ConnectionPoolable {
// validate checks if the connection is still usable
mut:
validate() !bool
// close terminates the physical connection
close() !
// reset returns the connection to initial state for reuse
reset() !
}
ConnectionPoolable defines the interface for connection objects
enum EvictionPriority #
enum EvictionPriority {
low // Routine cleanup (connection return)
medium // Connection get failure
high // Configuration change
urgent // Database/Server recovery
}
EvictionPriority indicates urgency of connection cleanup
struct ConnectionPool #
struct ConnectionPool {
mut:
config ConnectionPoolConfig
// Lock order:
// config_mutex > create_mutex > idle_pool_mutex > all_conns_mutex > wait_queue_mutex
config_mutex &sync.RwMutex @[required] // Guards configuration changes
create_mutex &sync.Mutex // Serializes connection creation
idle_pool_mutex &sync.RwMutex @[required] // Protects idle connections
all_conns_mutex &sync.RwMutex @[required] // Protects all connections map
wait_queue_mutex &sync.RwMutex @[required] // Protects wait queue
is_closed &stdatomic.AtomicVal[bool] @[required] // Pool shutdown flag
stop_ch chan bool // Signals maintenance thread to stop
eviction_ch chan EvictionPriority // Eviction event channel
cleanup_thread thread // Background maintenance thread
wait_queue []chan bool // Client wait queue for connection acquisition
conn_factory fn () !&ConnectionPoolable @[required] // Creates new connections
active_count &stdatomic.AtomicVal[int] @[required] // Currently checked-out connections
created_at time.Time // Pool creation timestamp
all_conns map[voidptr]&ConnectionWrapper // All tracked connections
idle_pool []&ConnectionWrapper // Currently idle connections
creation_errors &stdatomic.AtomicVal[int] @[required] // Failed creation attempts
evicted_count &stdatomic.AtomicVal[int] @[required] // Connections forcibly removed
creating_count &stdatomic.AtomicVal[int] @[required] // Connections being created
}
ConnectionPool manages a pool of reusable connections
fn (ConnectionPool) get #
fn (mut p ConnectionPool) get() !&ConnectionPoolable
get acquires a connection from the pool with timeout
fn (ConnectionPool) put #
fn (mut p ConnectionPool) put(conn &ConnectionPoolable) !
put returns a connection to the pool
fn (ConnectionPool) close #
fn (mut p ConnectionPool) close()
close shuts down the connection pool and cleans up resources
fn (ConnectionPool) update_config #
fn (mut p ConnectionPool) update_config(config ConnectionPoolConfig) !
update_config changes the connection pool configuration
fn (ConnectionPool) signal_recovery_event #
fn (mut p ConnectionPool) signal_recovery_event()
signal_recovery_event notifies the pool of recovery event
fn (ConnectionPool) send_eviction #
fn (mut p ConnectionPool) send_eviction(priority EvictionPriority)
send_eviction triggers a cleanup event
fn (ConnectionPool) stats #
fn (mut p ConnectionPool) stats() ConnectionPoolStats
stats retrieves current connection pool statistics
struct ConnectionPoolConfig #
struct ConnectionPoolConfig {
pub mut:
max_conns int = 20 // Maximum allowed connections
min_idle_conns int = 5 // Minimum idle connections to maintain
max_lifetime time.Duration = time.hour // Max lifetime of a connection
idle_timeout time.Duration = 30 * time.minute // Time before idle connections are cleaned up
get_timeout time.Duration = 5 * time.second // Max time to wait for a connection
retry_base_delay time.Duration = 1 * time.second // Base delay for retry backoff
max_retry_delay time.Duration = 30 * time.second // Maximum delay for retry backoff
max_retry_attempts int = 5 // Maximum retry attempts
}
ConnectionPoolConfig holds configuration settings for the connection pool
struct ConnectionPoolStats #
struct ConnectionPoolStats {
pub:
total_conns int // All managed connections
active_conns int // Currently checked-out connections
idle_conns int // Available connections
waiting_clients int // Clients waiting for a connection
evicted_count int // Connections forcibly removed
creation_errors int // Failed creation attempts
created_at time.Time // When pool was created
creating_count int // Connections being created
}
ConnectionPoolStats holds statistics about the pool