Spaces:
Running
Running
Commit ·
0d96a43
1
Parent(s): fde4eb0
ok
Browse files
whatsapp-service/pkg/config/config.go
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
package config
|
| 2 |
|
| 3 |
import (
|
|
|
|
| 4 |
"database/sql"
|
| 5 |
"fmt"
|
| 6 |
"net"
|
|
@@ -80,7 +81,11 @@ func (c *Config) CreateSupabaseDB() (*sql.DB, error) {
|
|
| 80 |
return nil, fmt.Errorf("SUPABASE_DB_URL is required for the whatsmeow session store")
|
| 81 |
}
|
| 82 |
|
|
|
|
|
|
|
|
|
|
| 83 |
dsn := forceIPv4DSN(c.SupabaseDBURL)
|
|
|
|
| 84 |
|
| 85 |
db, err := sql.Open("postgres", dsn)
|
| 86 |
if err != nil {
|
|
@@ -92,7 +97,9 @@ func (c *Config) CreateSupabaseDB() (*sql.DB, error) {
|
|
| 92 |
db.SetConnMaxLifetime(5 * time.Minute)
|
| 93 |
db.SetConnMaxIdleTime(1 * time.Minute)
|
| 94 |
|
| 95 |
-
|
|
|
|
|
|
|
| 96 |
return nil, fmt.Errorf("failed to ping Supabase Postgres (SUPABASE_DB_URL): %v", err)
|
| 97 |
}
|
| 98 |
|
|
@@ -100,6 +107,24 @@ func (c *Config) CreateSupabaseDB() (*sql.DB, error) {
|
|
| 100 |
return db, nil
|
| 101 |
}
|
| 102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
// forceIPv4DSN rewrites the DSN host to its resolved IPv4 address. Container
|
| 104 |
// runtimes (HF Spaces, many CI/cloud networks) frequently have no IPv6 route;
|
| 105 |
// a hostname whose DNS returns only an AAAA record first then fails to connect
|
|
|
|
| 1 |
package config
|
| 2 |
|
| 3 |
import (
|
| 4 |
+
"context"
|
| 5 |
"database/sql"
|
| 6 |
"fmt"
|
| 7 |
"net"
|
|
|
|
| 81 |
return nil, fmt.Errorf("SUPABASE_DB_URL is required for the whatsmeow session store")
|
| 82 |
}
|
| 83 |
|
| 84 |
+
// Force IPv4 and enforce a dial timeout so a silent network hang (e.g. an
|
| 85 |
+
// IPv6-only host, a blackholed route) fails fast with a clear error instead
|
| 86 |
+
// of blocking startup indefinitely.
|
| 87 |
dsn := forceIPv4DSN(c.SupabaseDBURL)
|
| 88 |
+
dsn = withConnectTimeout(dsn, 10)
|
| 89 |
|
| 90 |
db, err := sql.Open("postgres", dsn)
|
| 91 |
if err != nil {
|
|
|
|
| 97 |
db.SetConnMaxLifetime(5 * time.Minute)
|
| 98 |
db.SetConnMaxIdleTime(1 * time.Minute)
|
| 99 |
|
| 100 |
+
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
| 101 |
+
defer cancel()
|
| 102 |
+
if err := db.PingContext(ctx); err != nil {
|
| 103 |
return nil, fmt.Errorf("failed to ping Supabase Postgres (SUPABASE_DB_URL): %v", err)
|
| 104 |
}
|
| 105 |
|
|
|
|
| 107 |
return db, nil
|
| 108 |
}
|
| 109 |
|
| 110 |
+
// withConnectTimeout appends (or updates) lib/pq's connect_timeout parameter.
|
| 111 |
+
func withConnectTimeout(dsn string, seconds int) string {
|
| 112 |
+
q := url.Values{}
|
| 113 |
+
if u, err := url.Parse(dsn); err == nil {
|
| 114 |
+
for k, vs := range u.Query() {
|
| 115 |
+
for _, v := range vs {
|
| 116 |
+
q.Add(k, v)
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
q.Set("connect_timeout", strconv.Itoa(seconds))
|
| 121 |
+
if u, err := url.Parse(dsn); err == nil {
|
| 122 |
+
u.RawQuery = q.Encode()
|
| 123 |
+
return u.String()
|
| 124 |
+
}
|
| 125 |
+
return dsn
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
// forceIPv4DSN rewrites the DSN host to its resolved IPv4 address. Container
|
| 129 |
// runtimes (HF Spaces, many CI/cloud networks) frequently have no IPv6 route;
|
| 130 |
// a hostname whose DNS returns only an AAAA record first then fails to connect
|