Help us shape the future of Go! Take the 2026 Go Developer Survey

dbready

package
v1.16.0 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 9 Imported by: 1

Documentation

Overview

Package dbready — ограниченное ожидание готовности Postgres принимать соединения.

Зачем. Init-контейнер `migrate` стартует одновременно с подом Postgres и не ждёт его. Мигратор при этом умирает на ПЕРВОЙ же неудаче (`log.Fatalf`), под уходит в CrashLoopBackOff и «самоизлечивается» только когда PG наконец поднялся. Формально это работает, фактически — шум, который маскирует НАСТОЯЩИЕ сбои старта: в логах и событиях невозможно отличить «PG ещё не успел» от «неверный пароль» / «миграция сломана», потому что обе выглядят одинаково — рестарт.

Что делает пакет. Ждёт ТОЛЬКО класс «БД ещё не принимает соединения» (см. IsNotReady) и ТОЛЬКО в пределах бюджета. Любая другая ошибка возвращается немедленно — конфигурационный дефект обязан падать сразу, а не прятаться под двухминутным ожиданием.

Почему именно Ping, а не «обернуть sql.Open в retry». `sql.Open` ЛЕНИВ: он не дозванивается до сервера и почти никогда не ошибается. Гонка проявляется позже — на первом реальном запросе (у нас это `goose.Up`). Retry вокруг `sql.Open` был бы полностью бесполезен; поэтому барьер ставится явным `PingContext` ДО goose.

Index

Constants

View Source
const (
	// SQLStateCannotConnectNow — 57P03 "the database system is starting up".
	// Канонический признак того, что PG поднялся, но ещё проигрывает WAL.
	SQLStateCannotConnectNow = "57P03"
	// SQLStateAdminShutdown — 57P01, сервер завершается (rolling restart).
	SQLStateAdminShutdown = "57P01"
	// SQLStateCrashShutdown — 57P02, сервер перезапускается после сбоя бэкенда.
	SQLStateCrashShutdown = "57P02"
	// SQLStateTooManyConnections — 53300; на bring-up пул ещё не разошёлся.
	SQLStateTooManyConnections = "53300"
)

SQLState-коды, означающие «сервер жив, но пока не обслуживает» — не путать с ошибками аутентификации/схемы.

View Source
const (
	DefaultInitialInterval = 250 * time.Millisecond
	DefaultMaxInterval     = 5 * time.Second
	DefaultMaxElapsed      = 2 * time.Minute
)

Значения по умолчанию. Бюджет 2 минуты покрывает холодный старт Postgres (initdb + WAL replay) с запасом и при этом ОГРАНИЧЕН: вечно висящий init-контейнер хуже CrashLoopBackOff — он не даёт ни сигнала, ни рестарта.

Variables

This section is empty.

Functions

func IsNotReady

func IsNotReady(err error) bool

IsNotReady сообщает, означает ли ошибка «Postgres ещё не принимает соединения».

Классификация — сердце пакета: false там, где нужно true, вернёт CrashLoopBackOff; true там, где нужно false, спрячет конфигурационный дефект (неверный пароль, несуществующая БД) под таймаутом ожидания. Поэтому список намеренно УЗКИЙ: транспорт (dial/DNS/reset/EOF) + SQLSTATE-класс 08 (connection_exception) + явные «сервер стартует/выключается/перегружен». Всё остальное — включая 28P01 (bad password), 3D000 (no such database), 42501 (no privilege) и любые ошибки самих миграций — настоящая ошибка.

func Wait

func Wait(ctx context.Context, p Pinger, opts Options) error

Wait пингует БД, пока она не начнёт отвечать, но не дольше opts.MaxElapsed.

Возврат:

  • nil — БД принимает соединения;
  • исходная ошибка, если она НЕ из класса «не готов» (fail-fast, без ретраев);
  • ошибка с бюджетом и последней причиной, если БД так и не поднялась;
  • ctx.Err(), если контекст отменён (SIGTERM init-контейнера).

РЕПЛИКИ: запрос — петля принадлежит вызову — ожиданию готовности базы при старте — и завершается по его условию. Ничего не пишет: только опрашивает.

Types

type Options

type Options struct {
	InitialInterval time.Duration
	MaxInterval     time.Duration
	MaxElapsed      time.Duration
}

Options — параметры ожидания. Нулевое значение валидно: каждое поле подставляется дефолтом.

type Pinger

type Pinger interface {
	PingContext(ctx context.Context) error
}

Pinger — минимальный контракт, который реализует *sql.DB. Интерфейс (а не *sql.DB) держит пакет юнит-тестируемым без живого Postgres.

Jump to

Keyboard shortcuts

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