A generic, thread-safe connection pool implementation for managing and reusing connections with features like health checks, size limits, idle connection management, and metrics tracking.
- Thread-safe: Designed for concurrent use across multiple goroutines.
- Connection Lifecycle Management: Automatic creation (
Factory), reuse (Put), and closing (Close). - Configurable Limits:
MaxSize: Maximum total connections (active + idle).MaxIdle: Maximum idle connections to keep.MaxIdleTime: Maximum time a connection can remain idle before being closed by cleanup.MaxAge: Maximum time a connection can exist before being closed by cleanup.
- Connection Health Checking:
- Optional
Pingfunction to verify connection health. - Automatic periodic health checks for idle connections (
HealthCheckInterval,HealthCheckTimeout). - Optional ping-on-get (performed when
Pingis set).
- Optional
- Idle Connection Cleanup: Background goroutine removes connections exceeding
MaxIdleTimeorMaxAge. - Waiting Mechanism:
Getblocks and waits if the pool is atMaxSizeuntil a connection is returned or the context times out. - Context Awareness:
Get,Close,Factory, andPingoperations respectcontext.Contextcancellation and deadlines. - Explicit Discard:
Discardmethod to remove known broken connections from the pool. - Comprehensive Metrics: Tracks gets, puts, hits, misses, waits, timeouts, connection closures, and more via
Stats(). - Graceful Shutdown:
Closemethod waits for active connections to be returned (respecting context).
go get github.com/briceamen/connpoolpackage main
import (
"context"
"net"
"time"
"github.com/briceamen/connpool"
)
func main() {
// Define connection factory
factory := func(ctx context.Context) (interface{}, error) {
return net.Dial("tcp", "example.com:80")
}
// Define connection close function
closeFunc := func(conn interface{}) error {
return conn.(net.Conn).Close()
}
// Optional ping function to check connection health
pingFunc := func(conn interface{}) error {
return nil // Implement real connection check
}
// Create pool configuration
config := connpool.Config{
Factory: factory,
Close: closeFunc,
Ping: pingFunc,
MaxSize: 10,
MaxIdle: 5,
MaxIdleTime: time.Minute * 5,
}
// Initialize the pool
pool, err := connpool.NewPool(config)
if err != nil {
panic(err)
}
defer pool.Close(context.Background())
// Get a connection
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
conn, err := pool.Get(ctx)
if err != nil {
panic(err)
}
// Use the connection...
// Return the connection to the pool when done
pool.Put(conn)
// Or discard it if there was an error
// pool.Discard(conn)
// Check metrics
stats := pool.Stats()
println("Total connections:", pool.Len())
println("Idle connections:", pool.IdleLen())
println("Hits:", stats.Hits)
println("Misses:", stats.Misses)
}The Config struct allows you to configure the pool behavior:
| Field | Description |
|---|---|
Factory |
Function that creates new connections (required) |
Close |
Function that closes connections (required) |
Ping |
Optional function to check connection health |
MaxSize |
Maximum number of connections in the pool (active + idle) |
MaxIdle |
Maximum number of idle connections to keep |
MaxIdleTime |
Maximum time a connection can remain idle before being closed by the background cleanup goroutine |
MaxAge |
Maximum time a connection can exist before being closed by the background cleanup goroutine |
HealthCheckInterval |
Interval for performing background health checks (Ping) on idle connections |
HealthCheckTimeout |
Timeout duration for a single background health check (Ping) |
CleanupInterval |
Explicit interval for the background cleanup goroutine (overrides defaults based on MaxIdleTime/HealthCheckInterval) |
The package defines several errors in errors.go:
ErrPoolClosed: Operation attempted on a closed poolErrFactoryRequired: Pool initialized with nil FactoryErrCloseFuncRequired: Pool initialized with nil CloseFuncErrInvalidConnection: Invalid connection passed to Put/DiscardErrInvalidConfigMaxSize: MaxSize is set to 0ErrGetTimeout: Get timed out waiting for a connectionErrCloseTimeout: Close timed out waiting for connections
The Metrics struct provides detailed statistics about pool operations:
Gets: Total number of Get callsPuts: Total number of Put callsDiscards: Total number of Discard callsHits: Number of times Get returned an idle connectionMisses: Number of times Get created a new connectionWaits: Number of times Get had to waitTimeouts: Number of times Get timed outPingFailures: Number of connections discarded due to failed pingIdleClosed: Number of idle connections closed by the background cleanup (MaxIdleTime)AgeClosed: Number of connections closed due to MaxAgeFactoryFailures: Number of times the factory failed to create a connectionCloseTimeouts: Number of times Close timed out waiting for active connectionsMaxActive: Maximum active connections observed