You've already forked agentic-coding-workflow
55 lines
1.6 KiB
Go
55 lines
1.6 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// 默认连接池配置:10–50 用户私部署量级够用;超出后再按实际负载调整。
|
|
const (
|
|
defaultMaxConns = 20
|
|
defaultMinConns = 2
|
|
defaultMaxConnLifetime = time.Hour
|
|
defaultPingTimeout = 5 * time.Second
|
|
defaultHealthTimeout = time.Second
|
|
)
|
|
|
|
// Pool 是 pgxpool.Pool 的类型别名,外部代码可直接以 db.Pool 表达连接池类型,
|
|
// 同时保留 pgx 原生方法(Acquire/Exec/Query/...)。
|
|
type Pool = pgxpool.Pool
|
|
|
|
// NewPool 根据 dsn 构建 Postgres 连接池,并在返回前用 5s 超时的 Ping 做健康验证。
|
|
// 失败时关闭已创建的池并返回错误,避免泄露资源。
|
|
func NewPool(ctx context.Context, dsn string) (*Pool, error) {
|
|
cfg, err := pgxpool.ParseConfig(dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parse dsn: %w", err)
|
|
}
|
|
cfg.MaxConns = defaultMaxConns
|
|
cfg.MinConns = defaultMinConns
|
|
cfg.MaxConnLifetime = defaultMaxConnLifetime
|
|
|
|
pool, err := pgxpool.NewWithConfig(ctx, cfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("new pool: %w", err)
|
|
}
|
|
|
|
pingCtx, cancel := context.WithTimeout(ctx, defaultPingTimeout)
|
|
defer cancel()
|
|
if err := pool.Ping(pingCtx); err != nil {
|
|
pool.Close()
|
|
return nil, fmt.Errorf("ping: %w", err)
|
|
}
|
|
return pool, nil
|
|
}
|
|
|
|
// HealthCheck 用 1s 超时探测数据库连通性,供 healthz/readyz 等探针调用。
|
|
func HealthCheck(ctx context.Context, pool *Pool) error {
|
|
c, cancel := context.WithTimeout(ctx, defaultHealthTimeout)
|
|
defer cancel()
|
|
return pool.Ping(c)
|
|
}
|