Documentation
¶
Overview ¶
Package postgres implements leaderelection.Store on top of PostgreSQL using pgx.
It is designed to behave identically on a direct connection and through PgBouncer in transaction pooling mode, which is the usual way a fleet spread across clusters reaches a shared database. Nothing here uses session-scoped state: no session advisory locks, no LISTEN/NOTIFY, no temporary tables, no SET, and no server-side prepared statements. Every operation is a single autocommit statement.
The election's guarantees depend on all timestamps coming from the database server, so every statement returns the server's current time alongside the lease. See the leaderelection package documentation for why.
Index ¶
- Constants
- func Fatal(err error) bool
- func Retryable(err error) bool
- func Schema(schema, table string) (string, error)
- func SchemaSQL(opts ...Option) (string, error)
- type Option
- type Store
- func (s *Store) Acquire(ctx context.Context, name, identity string, ttl time.Duration, payload []byte) (leaderelection.Lease, error)
- func (s *Store) CheckSchema(ctx context.Context) error
- func (s *Store) Close()
- func (s *Store) EnsureSchema(ctx context.Context) errordeprecated
- func (s *Store) Inspect(ctx context.Context, name string) (leaderelection.Lease, error)
- func (s *Store) Release(ctx context.Context, name, identity string, fence int64) error
- func (s *Store) Renew(ctx context.Context, name, identity string, fence int64, ttl time.Duration, ...) (leaderelection.Lease, error)
- func (s *Store) Table() string
Constants ¶
const DefaultTable = "leader_election"
DefaultTable is the table name used when none is configured.
Variables ¶
This section is empty.
Functions ¶
func Fatal ¶
Fatal reports whether err describes a deployment problem that will not resolve without intervention: a missing table, missing privileges, a schema that does not match.
It is the signal worth alerting on. A fatal error means this participant will never win an election until somebody fixes something.
func Retryable ¶
Retryable reports whether err is a transient condition that is expected to clear on its own: a dropped connection, a pooler cycling, a deadlock, a serialization conflict, an administrator bouncing the server, a call that ran out of time.
A retryable error means the operation may be attempted again. It never means the caller may assume it is still the leader.
Errors are classified as this package returns them, which is wrapped. Every check here goes through errors.Is or errors.As for that reason.
func Schema ¶
Schema returns the initial DDL for an external migration tool. See SchemaSQL to use the same options and defaults as New.
schema may be empty to use the connection's search path. Both identifiers are validated, and Schema returns an error rather than emitting anything it could not validate.
func SchemaSQL ¶
SchemaSQL returns the initial table DDL without connecting to a database. It accepts the same options and defaults as New and Connect. Apply the SQL through your migration tool with a separate privileged identity before starting services. It does not upgrade or validate an existing table.
Types ¶
type Option ¶
type Option func(*options)
Option configures a Store.
func WithTable ¶
WithTable selects the table holding the leases. schema may be empty to use the connection's search path.
Both identifiers must be simple unquoted names; anything else is rejected rather than quoted, because the table name is the only part of these statements that cannot be a bind parameter.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a PostgreSQL-backed leaderelection.Store.
func Connect ¶
Connect builds a pool from dsn and returns a Store that owns it. It does not create or migrate tables; provision them separately with SchemaSQL.
The pool is configured to work through PgBouncer in transaction pooling mode as well as directly:
- The query exec mode is pgx.QueryExecModeExec, which sends each statement without naming a prepared statement on the server. Named prepared statements are per-session, so under transaction pooling they end up on whichever server connection the pooler hands out next and produce "prepared statement does not exist" at random. The cost is negligible for the handful of statements this package runs.
- The statement and description caches are disabled for the same reason.
- Connection lifetimes and health checks are bounded, so the pool sheds connections that a pooler restart left in an unusable state instead of discovering them one failed election at a time.
Settings expressed in dsn are honoured, with one exception. pgx does not distinguish "the DSN asked for cache_statement" from "the DSN said nothing", so a DSN that asks for it explicitly is still moved to exec mode. Any other exec mode is left alone, and a caller who wants statement caching against a direct connection can build the pool themselves and pass it to New.
func New ¶
New returns a Store that uses db. It does not query or modify the schema. Provision the table separately with SchemaSQL before running elections.
The caller keeps ownership of the pool: Store.Close does not close it. Use this when the application already has a pool, and Connect when it does not.
A pool built by the caller must tolerate a connection pooler if one is in the path. In particular its query exec mode must not rely on named prepared statements; see Connect for the settings this package would have chosen.
func (*Store) Acquire ¶
func (s *Store) Acquire(ctx context.Context, name, identity string, ttl time.Duration, payload []byte) (leaderelection.Lease, error)
Acquire implements leaderelection.Store.
func (*Store) CheckSchema ¶
CheckSchema checks that the configured table and required columns can be selected. It performs one read-only query, returns no lease data, and works on an empty table. It never creates, alters, or repairs the schema.
This is a connectivity and column-access check, not a migration validator: it does not verify column types, constraints, indexes, or INSERT/UPDATE privileges. Schema correctness remains the migration process's responsibility.
func (*Store) Close ¶
func (s *Store) Close()
Close releases resources the Store owns. A pool passed to New belongs to the caller and is left open; one created by Connect is closed.
func (*Store) EnsureSchema
deprecated
EnsureSchema creates the leases table if it does not exist. It requires DDL privileges and does not validate or upgrade an existing table.
Deprecated: provision tables through a separate migration process using SchemaSQL. Use Store.CheckSchema for a read-only startup check.
func (*Store) Inspect ¶
Inspect implements leaderelection.Store.
func (*Store) Release ¶
Release implements leaderelection.Store.