Add dbx library: PostgreSQL cluster with master/replica routing, retry, health checking
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
88
config.go
Normal file
88
config.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package dbx
|
||||
|
||||
import "time"
|
||||
|
||||
// Config is the top-level configuration for a Cluster.
|
||||
type Config struct {
|
||||
Master NodeConfig
|
||||
Replicas []NodeConfig
|
||||
Retry RetryConfig
|
||||
Logger Logger
|
||||
Metrics *MetricsHook
|
||||
HealthCheck HealthCheckConfig
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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:])
|
||||
}
|
||||
Reference in New Issue
Block a user