package dbx import ( "time" "github.com/jackc/pgx/v5" ) // Config is the top-level configuration for a Cluster. type Config struct { Master NodeConfig Replicas []NodeConfig Retry RetryConfig Logger Logger Metrics *MetricsHook HealthCheck HealthCheckConfig SlowQueryThreshold time.Duration } // NodeConfig describes a single database node. type NodeConfig struct { Name string // human-readable name for logs/metrics, e.g. "master", "replica-1" DSN string Pool PoolConfig Tracer pgx.QueryTracer } // PoolConfig controls pgxpool.Pool parameters. type PoolConfig struct { MaxConns int32 MinConns int32 MaxConnLifetime time.Duration MaxConnIdleTime time.Duration HealthCheckPeriod time.Duration } // RetryConfig controls retry behaviour. type RetryConfig struct { MaxAttempts int // default: 3 BaseDelay time.Duration // default: 50ms MaxDelay time.Duration // default: 1s RetryableErrors func(error) bool // optional custom classifier } // HealthCheckConfig controls the background health checker. type HealthCheckConfig struct { Interval time.Duration // default: 5s Timeout time.Duration // default: 2s } // defaults fills zero-valued fields with sensible defaults. func (c *Config) defaults() { if c.Logger == nil { c.Logger = nopLogger{} } if c.Retry.MaxAttempts <= 0 { c.Retry.MaxAttempts = 3 } if c.Retry.BaseDelay <= 0 { c.Retry.BaseDelay = 50 * time.Millisecond } if c.Retry.MaxDelay <= 0 { c.Retry.MaxDelay = time.Second } if c.HealthCheck.Interval <= 0 { c.HealthCheck.Interval = 5 * time.Second } if c.HealthCheck.Timeout <= 0 { c.HealthCheck.Timeout = 2 * time.Second } if c.Master.Name == "" { c.Master.Name = "master" } for i := range c.Replicas { if c.Replicas[i].Name == "" { c.Replicas[i].Name = "replica-" + itoa(i+1) } } } // itoa is a minimal int-to-string without importing strconv. func itoa(n int) string { if n == 0 { return "0" } buf := [20]byte{} i := len(buf) for n > 0 { i-- buf[i] = byte('0' + n%10) n /= 10 } return string(buf[i:]) }