@@ -88,6 +88,7 @@ import (
88
88
"github.com/coder/coder/provisionersdk"
89
89
sdkproto "github.com/coder/coder/provisionersdk/proto"
90
90
"github.com/coder/coder/tailnet"
91
+ "github.com/coder/retry"
91
92
"github.com/coder/wgtunnel/tunnelsdk"
92
93
)
93
94
@@ -1733,24 +1734,43 @@ func BuildLogger(inv *clibase.Invocation, cfg *codersdk.DeploymentValues) (slog.
1733
1734
1734
1735
func connectToPostgres (ctx context.Context , logger slog.Logger , driver string , dbURL string ) (* sql.DB , error ) {
1735
1736
logger .Debug (ctx , "connecting to postgresql" )
1736
- sqlDB , err := sql .Open (driver , dbURL )
1737
- if err != nil {
1738
- return nil , xerrors .Errorf ("dial postgres: %w" , err )
1739
- }
1740
1737
1741
- ok := false
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
+ }
1765
+ // Make sure we close the DB in case it opened but the ping failed for some
1766
+ // reason.
1742
1767
defer func () {
1743
- if ! ok {
1768
+ if ! ok && sqlDB != nil {
1744
1769
_ = sqlDB .Close ()
1745
1770
}
1746
1771
}()
1747
-
1748
- pingCtx , pingCancel := context .WithTimeout (ctx , 15 * time .Second )
1749
- defer pingCancel ()
1750
-
1751
- err = sqlDB .PingContext (pingCtx )
1752
1772
if err != nil {
1753
- return nil , xerrors .Errorf ("ping postgres: %w" , err )
1773
+ return nil , xerrors .Errorf ("connect to postgres; tries %d; last error : %w" , tries , err )
1754
1774
}
1755
1775
1756
1776
// Ensure the PostgreSQL version is >=13.0.0!
@@ -1799,6 +1819,12 @@ func connectToPostgres(ctx context.Context, logger slog.Logger, driver string, d
1799
1819
return sqlDB , nil
1800
1820
}
1801
1821
1822
+ func pingPostgres (ctx context.Context , db * sql.DB ) error {
1823
+ ctx , cancel := context .WithTimeout (ctx , 5 * time .Second )
1824
+ defer cancel ()
1825
+ return db .PingContext (ctx )
1826
+ }
1827
+
1802
1828
type HTTPServers struct {
1803
1829
HTTPUrl * url.URL
1804
1830
HTTPListener net.Listener
0 commit comments