Design and Implementation of a Generic Connection Pool in Go (Conecta)
This article explains the motivation, design principles, and implementation details of Conecta, a lightweight, configurable Go library that provides a universal connection pool for various services such as databases, TCP/UDP, and custom connections, complete with extensible callbacks and background health checks.
Author LEE, a veteran with 17 years in IT, introduces the need for a lightweight, universal connection pool for various services such as Redis, MySQL, MongoDB, TCP/UDP, etc., and explains why reinventing the wheel is inefficient.
He demonstrates how typical client SDKs (e.g., github.com/go-sql-driver/mysql ) provide built‑in pools, but custom scenarios require manual management.
After analyzing existing ad‑hoc implementations (map+lock, channel, third‑party wrappers), he proposes a generic pool built on a channel‑like queue, supporting configurable max connections, idle limits, ping checks, and custom callbacks.
Key design includes a NewPool constructor, Get , Put , GetOrCreate methods, a background goroutine that periodically pings connections, and extensible hooks ( WithNewFunc , WithPingFunc , WithCloseFunc , WithCallback , etc.).
func execSQL() error {
// 打开数据库
db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
return err
}
defer db.Close()
// 执行 SQL 语句
db.Exec("INSERT INTO user (name, age) VALUES (?, ?)", "老李", 18)
return nil
}The pool can be created with a simple configuration:
pool := NewPool(10, 30, 10*time.Second, func() (interface{}, error) {
// 创建一个 TCP 连接
return net.Dial("tcp", "192.168.0.1:80")
})
defer pool.Close()
conn, err := pool.Get()
if err != nil {
// handle error
}
if _, err := conn.Write([]byte("hello")); err != nil {
conn.Close()
return
}
pool.Put(conn)A periodic timer checks connection health:
// 创建一个定时器,每 p.config.scanInterval 毫秒触发一次
ticker := time.NewTicker(time.Millisecond * time.Duration(p.config.scanInterval))If a connection fails ping checks beyond the maximum retry count, it is closed and the user‑defined OnClose callback is invoked:
if retryCount >= p.config.maxRetries {
if value != nil {
err := p.config.closeFunc(value)
p.config.callback.OnClose(value, err)
element.SetData(nil)
}
} else {
if ok := p.config.pingFunc(value, retryCount); ok {
element.SetValue(0)
p.config.callback.OnPingSuccess(value)
} else {
element.SetValue(int64(retryCount) + 1)
p.config.callback.OnPingFailure(value)
}
}The Conecta library (https://github.com/shengyanli1982/conecta) offers a simple API, lifecycle management, and can be integrated with any queue implementation, aiming to reduce duplicated effort across projects.
Conclusion: Conecta provides a reusable, configurable connection‑pool solution for backend services, improving development efficiency and maintainability.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.