pgcluster

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package pgcluster connects to a PostgreSQL cluster over database/sql.

It keeps a pool per node and decides which one a query should use: the writer is discovered at runtime (by DNS, by pg_is_in_recovery(), or by probing for a writable transaction) so a failover does not need a restart, and reads are balanced across the healthy nodes. Failing nodes are dropped and retried, and a circuit breaker gives up quickly once the whole cluster is unreachable.

It returns *sql.DB, so an ORM binds to it in a few lines rather than being a dependency of this package.

Index

Constants

View Source
const CloudRDSExample = `` /* 514-byte string literal not displayed */

Query-Based Detection (Cloud RDS/Aurora)

View Source
const DefaultDriverName = "pgx"

DefaultDriverName is the database/sql driver used when ClusterConfig leaves DriverName empty. The package imports the pgx stdlib driver to register it; setting DriverName to something else requires the caller to import that driver instead.

View Source
const DevEnvExample = `` /* 188-byte string literal not displayed */

Single Database (Development)

View Source
const ProdClusterExample = `` /* 812-byte string literal not displayed */

Primary/Replica Cluster (Production)

Variables

This section is empty.

Functions

This section is empty.

Types

type ClusterConfig

type ClusterConfig struct {
	// Connection URLs
	WriterURL  string   // Primary writer connection
	ReaderURLs []string // Read replica connections

	// Writer detection
	WriterDetectionStrategy WriterDetectionStrategy
	WriterDetectionQuery    string // Custom query to detect writer
	WriterDNSName           string // DNS name that always points to writer

	// Connection pooling
	MaxOpenConns    int           // Maximum open connections per node
	MaxIdleConns    int           // Maximum idle connections per node
	ConnMaxLifetime time.Duration // Connection lifetime
	ConnMaxIdleTime time.Duration // Connection idle timeout

	// Health and retry settings
	HealthCheckInterval time.Duration // How often to check node health
	RetryAttempts       int           // Max retry attempts for connections
	RetryBackoffBase    time.Duration // Base backoff duration
	RetryBackoffMax     time.Duration // Maximum backoff duration

	// Circuit breaker
	CircuitBreakerThreshold int           // Failures before opening circuit
	CircuitBreakerTimeout   time.Duration // Circuit breaker timeout

	// Read balancing
	ReadBalanceStrategy string // "round_robin", "random", "priority", "least_connections"

	// Service identification
	ServiceName string

	// DriverName is the database/sql driver used to open each node.
	// Defaults to DefaultDriverName.
	DriverName string
}

ClusterConfig holds configuration for the database cluster manager

func LoadConfigFromEnv

func LoadConfigFromEnv(serviceName string) (*ClusterConfig, error)

LoadConfigFromEnv loads database cluster configuration from environment variables

func (*ClusterConfig) String

func (c *ClusterConfig) String() string

String returns a string representation of the configuration

func (*ClusterConfig) Validate

func (c *ClusterConfig) Validate() error

Validate ensures the configuration is valid

type ClusterManager

type ClusterManager struct {
	// contains filtered or unexported fields
}

ClusterManager manages connections to multiple PostgreSQL nodes

func NewClusterManager

func NewClusterManager(config ClusterConfig) (*ClusterManager, error)

NewClusterManager creates a new database cluster manager

func (*ClusterManager) Close

func (cm *ClusterManager) Close() error

Close gracefully shuts down all connections. Every node is closed even if an earlier one failed; the failures are joined into the returned error rather than discarded, which is what this method used to do.

func (*ClusterManager) DB

func (cm *ClusterManager) DB(ctx context.Context) (*sql.DB, error)

DB returns the writer when ctx carries a write hint from WithWriter, and a read replica otherwise.

func (*ClusterManager) ForceWriterDetection

func (cm *ClusterManager) ForceWriterDetection()

ForceWriterDetection triggers immediate writer detection

func (*ClusterManager) GetNodeStats

func (cm *ClusterManager) GetNodeStats() map[string]NodeStats

GetNodeStats returns statistics for all nodes

func (*ClusterManager) HealthCheck

func (cm *ClusterManager) HealthCheck() error

HealthCheck performs a comprehensive health check of the cluster

func (*ClusterManager) Reader

func (cm *ClusterManager) Reader() (*sql.DB, error)

Reader returns a connection pool for reads, chosen by the configured balancing strategy. The writer participates in read balancing alongside the replicas -- a primary serves reads too -- so a single-node deployment and a deployment whose replicas are all down both keep serving.

func (*ClusterManager) SetWriterNode

func (cm *ClusterManager) SetWriterNode(nodeName string) error

SetWriterNode manually sets a node as the writer (for emergencies)

func (*ClusterManager) WithReader

func (cm *ClusterManager) WithReader(ctx context.Context) context.Context

WithReader returns a context that routes DB to a read replica.

func (*ClusterManager) WithWriter

func (cm *ClusterManager) WithWriter(ctx context.Context) context.Context

WithWriter returns a context that routes DB to the writer.

func (*ClusterManager) Writer

func (cm *ClusterManager) Writer() (*sql.DB, error)

Writer returns the connection pool for the writer node.

type DatabaseNode

type DatabaseNode struct {
	URL      string
	Name     string
	Role     NodeRole
	Health   NodeHealth
	Priority int // Lower number = higher priority for reads
	// contains filtered or unexported fields
}

DatabaseNode represents a single PostgreSQL instance

type NodeHealth

type NodeHealth int

NodeHealth represents the health state of a database node

const (
	HealthHealthy NodeHealth = iota
	HealthDegraded
	HealthFailed
)

func (NodeHealth) String

func (h NodeHealth) String() string

type NodeRole

type NodeRole int

NodeRole represents the role of a database node

const (
	RoleWriter NodeRole = iota
	RoleReader
	RoleUnknown
)

func (NodeRole) String

func (r NodeRole) String() string

type NodeStats

type NodeStats struct {
	URL          string
	Role         NodeRole
	Health       NodeHealth
	Priority     int
	ReadCount    int64
	WriteCount   int64
	ErrorCount   int64
	ResponseTime time.Duration
	LastError    error
	LastCheck    time.Time
	PoolStats    sql.DBStats
}

NodeStats holds statistics for a single database node

type TombManager

type TombManager struct {
	// contains filtered or unexported fields
}

TombManager provides graceful background task management for database cluster components

func NewTombManager

func NewTombManager(serviceName string) *TombManager

NewTombManager creates a new background task manager for database operations

func (*TombManager) Context

func (tm *TombManager) Context() context.Context

Context returns the cancellation context for manual task management

func (*TombManager) IsShuttingDown

func (tm *TombManager) IsShuttingDown() bool

IsShuttingDown returns true if the tomb manager is shutting down

func (*TombManager) Shutdown

func (tm *TombManager) Shutdown()

Shutdown gracefully stops all background tasks

func (*TombManager) StartBackgroundTask

func (tm *TombManager) StartBackgroundTask(taskFn func(ctx context.Context), taskName string)

StartBackgroundTask starts a background task with proper lifecycle management

func (*TombManager) WaitGroup

func (tm *TombManager) WaitGroup() *sync.WaitGroup

WaitGroup returns the wait group for manual task management

type WriterDetectionStrategy

type WriterDetectionStrategy int

WriterDetectionStrategy defines how to detect the writer node

const (
	StrategyDNS    WriterDetectionStrategy = iota // DNS-based (writer.db.example.com)
	StrategyQuery                                 // SQL query-based detection
	StrategyConfig                                // Configuration-based (explicit writer)
	StrategyProbe                                 // Health probe-based detection
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL