Skip to content

Commit 615b33a

Browse files
committed
fix(server): retry initial connection to postgres
1 parent 8d1f163 commit 615b33a

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

cli/server.go

+37-12
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ import (
8888
"github.com/coder/coder/provisionersdk"
8989
sdkproto "github.com/coder/coder/provisionersdk/proto"
9090
"github.com/coder/coder/tailnet"
91+
"github.com/coder/retry"
9192
"github.com/coder/wgtunnel/tunnelsdk"
9293
)
9394

@@ -1733,26 +1734,44 @@ func BuildLogger(inv *clibase.Invocation, cfg *codersdk.DeploymentValues) (slog.
17331734

17341735
func connectToPostgres(ctx context.Context, logger slog.Logger, driver string, dbURL string) (*sql.DB, error) {
17351736
logger.Debug(ctx, "connecting to postgresql")
1736-
sqlDB, err := sql.Open(driver, dbURL)
1737+
1738+
// Try to connect for 30 seconds.
1739+
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
1740+
defer cancel()
1741+
1742+
var (
1743+
sqlDB *sql.DB
1744+
err error
1745+
ok = false
1746+
tries int
1747+
)
1748+
for r := retry.New(time.Second, 3*time.Second); r.Wait(ctx); {
1749+
tries++
1750+
1751+
sqlDB, err = sql.Open(driver, dbURL)
1752+
if err != nil {
1753+
logger.Warn(ctx, "connect to postgres; retrying", slog.Error(err), slog.F("try", tries))
1754+
continue
1755+
}
1756+
1757+
err = pingPostgres(ctx, sqlDB)
1758+
if err != nil {
1759+
logger.Warn(ctx, "ping postgres; retrying", slog.Error(err), slog.F("try", tries))
1760+
continue
1761+
}
1762+
1763+
break
1764+
}
17371765
if err != nil {
1738-
return nil, xerrors.Errorf("dial postgres: %w", err)
1766+
return nil, xerrors.Errorf("connect to postgres; tries %d; last error: %w", tries, err)
17391767
}
17401768

1741-
ok := false
17421769
defer func() {
1743-
if !ok {
1770+
if !ok && sqlDB != nil {
17441771
_ = sqlDB.Close()
17451772
}
17461773
}()
17471774

1748-
pingCtx, pingCancel := context.WithTimeout(ctx, 15*time.Second)
1749-
defer pingCancel()
1750-
1751-
err = sqlDB.PingContext(pingCtx)
1752-
if err != nil {
1753-
return nil, xerrors.Errorf("ping postgres: %w", err)
1754-
}
1755-
17561775
// Ensure the PostgreSQL version is >=13.0.0!
17571776
version, err := sqlDB.QueryContext(ctx, "SHOW server_version_num;")
17581777
if err != nil {
@@ -1799,6 +1818,12 @@ func connectToPostgres(ctx context.Context, logger slog.Logger, driver string, d
17991818
return sqlDB, nil
18001819
}
18011820

1821+
func pingPostgres(ctx context.Context, db *sql.DB) error {
1822+
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
1823+
defer cancel()
1824+
return db.PingContext(ctx)
1825+
}
1826+
18021827
type HTTPServers struct {
18031828
HTTPUrl *url.URL
18041829
HTTPListener net.Listener

0 commit comments

Comments
 (0)