Skip to content

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

ParameterDefault ValueDescription
max_conns20Maximum connections in pool
min_idle_conns5Minimum idle connections to maintain
max_lifetime1 hourMax connection lifetime
idle_timeout30 minutesIdle connection timeout
get_timeout5 secondsConnection acquisition timeout
retry_base_delay1 secondBase delay for connection retries
max_retry_delay30 secondsMaximum retry delay
max_retry_attempts5Maximum 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

  1. Exponential Backoff: Connection creation uses exponential backoff with jitter
  2. Priority Eviction: Four priority levels for connection cleanup:
  • low: Routine maintenance
  • medium: Connection acquisition failure
  • high: Configuration changes
  • urgent: Connection recovery events
  1. Adaptive Cleanup: Maintenance thread dynamically adjusts processing frequency
  2. Wait Queue: Fair connection allocation to waiting clients
  3. 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 #

@[params]
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