Skip to content

Commit 48ce8f3

Browse files
committed
Fix Postgres Docker flake and update 14.4 -> 14.6
This PR fixes an issue with our Docker Postgres connection where we sometimes connect before Postgres is fully up, see [1] for more details. [1] docker-library/postgres#146
1 parent 335519c commit 48ce8f3

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

Diff for: example/golden/raw_dump.sql

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
-- PostgreSQL database dump
33
--
44

5-
-- Dumped from database version 14.4 (Debian 14.4-1.pgdg110+1)
6-
-- Dumped by pg_dump version 14.4 (Debian 14.4-1.pgdg110+1)
5+
-- Dumped from database version 14.6 (Debian 14.6-1.pgdg110+1)
6+
-- Dumped by pg_dump version 14.6 (Debian 14.6-1.pgdg110+1)
77

88
SET statement_timeout = 0;
99
SET lock_timeout = 0;

Diff for: testpgx.go

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package testpgx
22

33
import (
4+
"bufio"
45
"context"
56
"database/sql"
67
"errors"
@@ -19,8 +20,8 @@ import (
1920
"github.com/google/uuid"
2021
"github.com/hashicorp/go-multierror"
2122
"github.com/jackc/pgx/v4"
22-
"github.com/jackc/pgx/v4/pgxpool"
2323

24+
"github.com/jackc/pgx/v4/pgxpool"
2425
pgxstdlib "github.com/jackc/pgx/v4/stdlib"
2526
)
2627

@@ -78,7 +79,7 @@ const (
7879
testDBUser = "postgres"
7980
testDBPass = "anypassword"
8081

81-
defaultPostgresImage = "postgres:14.4"
82+
defaultPostgresImage = "postgres:14.6"
8283
defaultMaxDBs = 10
8384
)
8485

@@ -180,6 +181,31 @@ func New(ctx context.Context, opts ...Option) (*Env, error) {
180181
return nil, fmt.Errorf("when getting postgres cid: %w", err)
181182
}
182183

184+
// Postgres starts up twice, first as an initialization phase, and then for
185+
// real. See this thread [1] for more info.
186+
// [1] https://github.com/docker-library/postgres/issues/146
187+
pgLogCtx, pgLogDone := context.WithCancel(ctx)
188+
defer pgLogDone()
189+
pgLogCmd := exec.CommandContext(pgLogCtx, o.dockerBinaryPath, "logs", "-f", cID)
190+
pgLogs, err := pgLogCmd.StdoutPipe()
191+
if err != nil {
192+
return nil, fmt.Errorf("failed to get stdout pipe for docker logs: %w", err)
193+
}
194+
if err := pgLogCmd.Start(); err != nil {
195+
return nil, fmt.Errorf("failed to start docker logs: %w", err)
196+
}
197+
initDone := make(chan struct{})
198+
go func() {
199+
sc := bufio.NewScanner(pgLogs)
200+
for sc.Scan() {
201+
if strings.Contains(sc.Text(), "PostgreSQL init process complete; ready for start up.") {
202+
break
203+
}
204+
}
205+
close(initDone)
206+
pgLogDone()
207+
}()
208+
183209
env := &Env{
184210
postgresCid: cID,
185211
canCreateDB: make(chan struct{}, o.maxDBs),
@@ -195,6 +221,10 @@ func New(ctx context.Context, opts ...Option) (*Env, error) {
195221
}
196222

197223
err = waitForPostgresToBeReady(ctx, func(ctx context.Context) error {
224+
// Don't try to connect until initialization is done. Postgres starts up twice
225+
// in Docker, the first is just an initialization.
226+
<-initDone
227+
198228
pool, err := pgxpool.Connect(ctx, env.dsn("" /* dbName */))
199229
if err != nil {
200230
return fmt.Errorf("failed to connect to database instance: %w", err)

0 commit comments

Comments
 (0)