Update kit with new pg config

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-04-22 22:29:53 +02:00
parent 7be92defcc
commit 990dfa8438
12 changed files with 101 additions and 29 deletions

View File

@@ -42,6 +42,9 @@
# PG_PASSWORD=postgres
# PG_DATABASE=probod
# PG_POOL_SIZE=100
# PG_MIN_POOL_SIZE=10
# PG_MAX_CONN_IDLE_TIME_SECONDS=1800
# PG_MAX_CONN_LIFETIME_SECONDS=3600
# PG_DEBUG=false
# ── Object storage (SeaweedFS via compose) ────────────────────────────

View File

@@ -87,6 +87,12 @@ spec:
value: {{ include "probo.postgresql.database" . | quote }}
- name: PG_POOL_SIZE
value: {{ .Values.postgresql.poolSize | default "100" | quote }}
- name: PG_MIN_POOL_SIZE
value: {{ .Values.postgresql.minPoolSize | default "10" | quote }}
- name: PG_MAX_CONN_IDLE_TIME_SECONDS
value: {{ .Values.postgresql.maxConnIdleTimeSeconds | default "1800" | quote }}
- name: PG_MAX_CONN_LIFETIME_SECONDS
value: {{ .Values.postgresql.maxConnLifetimeSeconds | default "3600" | quote }}
{{- if .Values.postgresql.caBundle }}
- name: PG_CA_BUNDLE
valueFrom:

View File

@@ -210,6 +210,11 @@ postgresql:
username: "probod"
password: "CHANGE_ME_DB_PASSWORD"
poolSize: 200
# Keep 20 connections warm to absorb bursts without paying the
# TLS + PostgreSQL startup handshake on each acquire.
minPoolSize: 20
maxConnIdleTimeSeconds: 1800
maxConnLifetimeSeconds: 3600
# Uncomment if using TLS with custom CA
# caCertBundle: |
# -----BEGIN CERTIFICATE-----

View File

@@ -301,6 +301,16 @@ postgresql:
password: "" # REQUIRED when enabled=false: PostgreSQL password
database: probod
poolSize: 100
# Minimum number of warm connections kept in the pool. Raising this
# value avoids TLS + PostgreSQL startup handshake latency on bursty
# workloads (visible as spikes on pgxpool_acquire_duration_seconds).
minPoolSize: 10
# Maximum time a connection can be idle before being destroyed, in
# seconds. Default 1800 (30 minutes) matches pgx defaults.
maxConnIdleTimeSeconds: 1800
# Maximum lifetime of a connection before being recycled, in
# seconds. Default 3600 (1 hour) matches pgx defaults.
maxConnLifetimeSeconds: 3600
# PostgreSQL TLS/SSL configuration
# caBundle: |
# -----BEGIN CERTIFICATE-----

View File

@@ -263,8 +263,9 @@ func generateConfig() (string, error) {
"API_CORS_ALLOWED_ORIGINS": "http://localhost:18080",
// PG.
"PG_DATABASE": "probod_test",
"PG_POOL_SIZE": "10",
"PG_DATABASE": "probod_test",
"PG_POOL_SIZE": "10",
"PG_MIN_POOL_SIZE": "1",
// Auth.
"AUTH_COOKIE_SECURE": "false",

2
go.mod
View File

@@ -35,7 +35,7 @@ require (
github.com/vikstrous/dataloadgen v0.0.10
github.com/yuin/goldmark v1.4.13
go.gearno.de/crypto/uuid v0.1.1-0.20251208105319-3f587312a712
go.gearno.de/kit v0.6.0
go.gearno.de/kit v0.7.0
go.gearno.de/x/ref v0.0.0-20260216110753-a700c951377c
go.opentelemetry.io/otel v1.43.0
go.opentelemetry.io/otel/trace v1.43.0

4
go.sum
View File

@@ -334,8 +334,8 @@ github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.gearno.de/crypto/uuid v0.1.1-0.20251208105319-3f587312a712 h1:J5ccbcxFuwxe6Oa9fVi9FqQOo+n17ni4wbl9t4NuEzc=
go.gearno.de/crypto/uuid v0.1.1-0.20251208105319-3f587312a712/go.mod h1:fnIIvKO9QnsyLO3ZJLJT3r8KZv/p0FOeT5eZKilYWXg=
go.gearno.de/kit v0.6.0 h1:2O7Gdi8DCt6sWUKXDq+SJPHjNnV7N+pYHpsBMhfFqmU=
go.gearno.de/kit v0.6.0/go.mod h1:jWrI/mxd0F4GZApL0HgMextcEQoiy2YA1JVamSA/G0E=
go.gearno.de/kit v0.7.0 h1:0UfrkWmiqpbI4FImWEc/eVBkYD8dMMVshmWtSSiRqJY=
go.gearno.de/kit v0.7.0/go.mod h1:jWrI/mxd0F4GZApL0HgMextcEQoiy2YA1JVamSA/G0E=
go.gearno.de/x/panicf v0.1.1 h1:E3Cr9NB8Ry2EsvEG/1eHr7kplP3tEjTf5d56dTX64VQ=
go.gearno.de/x/panicf v0.1.1/go.mod h1:VnB8oF0UefMZcYeD4v+Wk4U5Z1uza7PHLlhT2CbNEbU=
go.gearno.de/x/ref v0.0.0-20260216110753-a700c951377c h1:rIVWwnNxHYu9aZhHkptXlNYTBJbY4ccaIAYjztVeaDc=

View File

@@ -81,13 +81,16 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
ExtraHeaderFields: make(map[string]string),
},
Pg: probod.PgConfig{
Addr: b.getEnvOrDefault("PG_ADDR", "localhost:5432"),
Username: b.getEnvOrDefault("PG_USERNAME", "postgres"),
Password: b.getEnvOrDefault("PG_PASSWORD", "postgres"),
Database: b.getEnvOrDefault("PG_DATABASE", "probod"),
PoolSize: int32(b.getEnvIntOrDefault("PG_POOL_SIZE", 100)),
CACertBundle: pgCACertBundle,
Debug: b.getEnvBoolOrDefault("PG_DEBUG", false),
Addr: b.getEnvOrDefault("PG_ADDR", "localhost:5432"),
Username: b.getEnvOrDefault("PG_USERNAME", "postgres"),
Password: b.getEnvOrDefault("PG_PASSWORD", "postgres"),
Database: b.getEnvOrDefault("PG_DATABASE", "probod"),
PoolSize: int32(b.getEnvIntOrDefault("PG_POOL_SIZE", 100)),
MinPoolSize: int32(b.getEnvIntOrDefault("PG_MIN_POOL_SIZE", 10)),
MaxConnIdleTimeSeconds: b.getEnvIntOrDefault("PG_MAX_CONN_IDLE_TIME_SECONDS", 1800),
MaxConnLifetimeSeconds: b.getEnvIntOrDefault("PG_MAX_CONN_LIFETIME_SECONDS", 3600),
CACertBundle: pgCACertBundle,
Debug: b.getEnvBoolOrDefault("PG_DEBUG", false),
},
Auth: probod.AuthConfig{
DisableSignup: b.getEnvBoolOrDefault("AUTH_DISABLE_SIGNUP", false),

View File

@@ -131,6 +131,9 @@ func TestBuilder_Build_Defaults(t *testing.T) {
assert.Equal(t, "postgres", cfg.Probod.Pg.Password)
assert.Equal(t, "probod", cfg.Probod.Pg.Database)
assert.Equal(t, int32(100), cfg.Probod.Pg.PoolSize)
assert.Equal(t, int32(10), cfg.Probod.Pg.MinPoolSize)
assert.Equal(t, 1800, cfg.Probod.Pg.MaxConnIdleTimeSeconds)
assert.Equal(t, 3600, cfg.Probod.Pg.MaxConnLifetimeSeconds)
assert.False(t, cfg.Probod.Pg.Debug)
// Auth config
@@ -233,6 +236,9 @@ func TestBuilder_Build_CustomValues(t *testing.T) {
env["PG_PASSWORD"] = "secret123"
env["PG_DATABASE"] = "probo_prod"
env["PG_POOL_SIZE"] = "200"
env["PG_MIN_POOL_SIZE"] = "25"
env["PG_MAX_CONN_IDLE_TIME_SECONDS"] = "900"
env["PG_MAX_CONN_LIFETIME_SECONDS"] = "7200"
env["PG_DEBUG"] = "true"
// Auth
env["AUTH_DISABLE_SIGNUP"] = "true"
@@ -310,6 +316,9 @@ func TestBuilder_Build_CustomValues(t *testing.T) {
assert.Equal(t, "secret123", cfg.Probod.Pg.Password)
assert.Equal(t, "probo_prod", cfg.Probod.Pg.Database)
assert.Equal(t, int32(200), cfg.Probod.Pg.PoolSize)
assert.Equal(t, int32(25), cfg.Probod.Pg.MinPoolSize)
assert.Equal(t, 900, cfg.Probod.Pg.MaxConnIdleTimeSeconds)
assert.Equal(t, 7200, cfg.Probod.Pg.MaxConnLifetimeSeconds)
assert.True(t, cfg.Probod.Pg.Debug)
// Auth
assert.True(t, cfg.Probod.Auth.DisableSignup)

View File

@@ -111,11 +111,14 @@ func TestWriteConfig_CompleteConfig(t *testing.T) {
ExtraHeaderFields: map[string]string{},
},
Pg: probod.PgConfig{
Addr: "localhost:5432",
Username: "postgres",
Password: "postgres",
Database: "probod",
PoolSize: 100,
Addr: "localhost:5432",
Username: "postgres",
Password: "postgres",
Database: "probod",
PoolSize: 100,
MinPoolSize: 10,
MaxConnIdleTimeSeconds: 1800,
MaxConnLifetimeSeconds: 3600,
},
Connectors: []probod.ConnectorConfig{
{
@@ -147,6 +150,9 @@ func TestWriteConfig_CompleteConfig(t *testing.T) {
assert.Equal(t, cfg.Unit.Tracing.MaxBatchSize, loaded.Unit.Tracing.MaxBatchSize)
assert.Equal(t, cfg.Probod.Api.Cors.AllowedOrigins, loaded.Probod.Api.Cors.AllowedOrigins)
assert.Equal(t, cfg.Probod.Pg.PoolSize, loaded.Probod.Pg.PoolSize)
assert.Equal(t, cfg.Probod.Pg.MinPoolSize, loaded.Probod.Pg.MinPoolSize)
assert.Equal(t, cfg.Probod.Pg.MaxConnIdleTimeSeconds, loaded.Probod.Pg.MaxConnIdleTimeSeconds)
assert.Equal(t, cfg.Probod.Pg.MaxConnLifetimeSeconds, loaded.Probod.Pg.MaxConnLifetimeSeconds)
require.Len(t, loaded.Probod.Connectors, 1)
assert.Equal(t, "SLACK", loaded.Probod.Connectors[0].Provider)
}

View File

@@ -17,18 +17,22 @@ package probod
import (
"crypto/x509"
"encoding/pem"
"time"
"go.gearno.de/kit/pg"
)
type PgConfig struct {
Addr string `json:"addr"`
Username string `json:"username"`
Password string `json:"password"`
Database string `json:"database"`
PoolSize int32 `json:"pool-size"`
CACertBundle string `json:"ca-cert-bundle"`
Debug bool `json:"debug"`
Addr string `json:"addr"`
Username string `json:"username"`
Password string `json:"password"`
Database string `json:"database"`
PoolSize int32 `json:"pool-size"`
MinPoolSize int32 `json:"min-pool-size"`
MaxConnIdleTimeSeconds int `json:"max-conn-idle-time-seconds"`
MaxConnLifetimeSeconds int `json:"max-conn-lifetime-seconds"`
CACertBundle string `json:"ca-cert-bundle"`
Debug bool `json:"debug"`
}
func (cfg PgConfig) Options(options ...pg.Option) []pg.Option {
@@ -40,6 +44,28 @@ func (cfg PgConfig) Options(options ...pg.Option) []pg.Option {
pg.WithPoolSize(cfg.PoolSize),
}
if cfg.MinPoolSize > 0 {
opts = append(opts, pg.WithMinPoolSize(cfg.MinPoolSize))
}
if cfg.MaxConnIdleTimeSeconds > 0 {
opts = append(
opts,
pg.WithMaxConnIdleTime(
time.Duration(cfg.MaxConnIdleTimeSeconds)*time.Second,
),
)
}
if cfg.MaxConnLifetimeSeconds > 0 {
opts = append(
opts,
pg.WithMaxConnLifetime(
time.Duration(cfg.MaxConnLifetimeSeconds)*time.Second,
),
)
}
if cfg.Debug {
opts = append(opts, pg.WithDebug())
}

View File

@@ -152,11 +152,14 @@ func New() *Implm {
Addr: "localhost:8080",
},
Pg: PgConfig{
Addr: "localhost:5432",
Username: "postgres",
Password: "postgres",
Database: "probod",
PoolSize: 100,
Addr: "localhost:5432",
Username: "postgres",
Password: "postgres",
Database: "probod",
PoolSize: 100,
MinPoolSize: 10,
MaxConnIdleTimeSeconds: 1800,
MaxConnLifetimeSeconds: 3600,
},
ChromeDPAddr: "localhost:9222",
Auth: AuthConfig{