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
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()!
// Use connection
// ... your operations ...
// 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_conns
to balance startup time and memory - Set
max_lifetime
according to your backend connection limits - Monitor
creation_errors
statistic to detect connection issues - Use
evicted_count
to 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 {
mut:
// validate checks if the connection is still usable
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