Files
nettopo-go/internal/config/config.go
T
PTah 6ad59c9990 fix: ограничить пул Postgres и реже писать прогресс скана
- DB_MAX_OPEN_CONNS (25), DB_MAX_IDLE_CONNS (10), DB_CONN_MAX_LIFETIME_SEC (1800)

- Throttle UpdateScan прогресса в Runner (500ms), меньше одновременных запросов к БД

Устраняет FATAL too many clients при больших сканах и частом опросе GetScan

Made-with: Cursor
2026-04-13 15:33:25 +10:00

94 lines
2.3 KiB
Go

package config
import (
"os"
"strconv"
"strings"
"time"
)
type Config struct {
HTTPAddr string
DBDSN string
StoreBackend string
RunMigrations bool
SNMPEnabled bool
SNMPCommunity string
ResetDBSecret string // NETTOPO_RESET_DB_SECRET — секрет для POST /api/admin/purge-scans
// Пул соединений к PostgreSQL (см. database/sql). По умолчанию ограничен, иначе при большом скане легко исчерпать max_connections на сервере.
DBMaxOpenConns int
DBMaxIdleConns int
DBConnMaxLifetime time.Duration
}
func FromEnv() Config {
addr := os.Getenv("HTTP_ADDR")
if addr == "" {
addr = ":8080"
}
dbDSN := os.Getenv("DB_DSN")
storeBackend := os.Getenv("STORE_BACKEND")
if storeBackend == "" {
if dbDSN != "" {
storeBackend = "postgres"
} else {
storeBackend = "memory"
}
}
runMigrations := true
if os.Getenv("RUN_MIGRATIONS") == "false" {
runMigrations = false
}
snmpEnabled := true
if os.Getenv("SNMP_ENABLED") == "false" {
snmpEnabled = false
}
snmpCommunity := os.Getenv("SNMP_COMMUNITY")
if snmpCommunity == "" {
snmpCommunity = "public"
}
maxOpen := intFromEnvMin("DB_MAX_OPEN_CONNS", 25, 1)
maxIdle := intFromEnvMin("DB_MAX_IDLE_CONNS", 10, 0)
if maxIdle > maxOpen {
maxIdle = maxOpen
}
connLife := 30 * time.Minute
if s := strings.TrimSpace(os.Getenv("DB_CONN_MAX_LIFETIME_SEC")); s != "" {
if sec, err := strconv.Atoi(s); err == nil {
if sec == 0 {
connLife = 0 // без ограничения времени жизни соединения
} else if sec > 0 {
connLife = time.Duration(sec) * time.Second
}
}
}
return Config{
HTTPAddr: addr,
DBDSN: dbDSN,
StoreBackend: storeBackend,
RunMigrations: runMigrations,
SNMPEnabled: snmpEnabled,
SNMPCommunity: snmpCommunity,
ResetDBSecret: strings.TrimSpace(os.Getenv("NETTOPO_RESET_DB_SECRET")),
DBMaxOpenConns: maxOpen,
DBMaxIdleConns: maxIdle,
DBConnMaxLifetime: connLife,
}
}
func intFromEnvMin(key string, def, min int) int {
s := strings.TrimSpace(os.Getenv(key))
if s == "" {
return def
}
n, err := strconv.Atoi(s)
if err != nil || n < min {
return def
}
return n
}