Update kit with new pg config
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -42,6 +42,9 @@
|
|||||||
# PG_PASSWORD=postgres
|
# PG_PASSWORD=postgres
|
||||||
# PG_DATABASE=probod
|
# PG_DATABASE=probod
|
||||||
# PG_POOL_SIZE=100
|
# 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
|
# PG_DEBUG=false
|
||||||
|
|
||||||
# ── Object storage (SeaweedFS via compose) ────────────────────────────
|
# ── Object storage (SeaweedFS via compose) ────────────────────────────
|
||||||
|
|||||||
@@ -87,6 +87,12 @@ spec:
|
|||||||
value: {{ include "probo.postgresql.database" . | quote }}
|
value: {{ include "probo.postgresql.database" . | quote }}
|
||||||
- name: PG_POOL_SIZE
|
- name: PG_POOL_SIZE
|
||||||
value: {{ .Values.postgresql.poolSize | default "100" | quote }}
|
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 }}
|
{{- if .Values.postgresql.caBundle }}
|
||||||
- name: PG_CA_BUNDLE
|
- name: PG_CA_BUNDLE
|
||||||
valueFrom:
|
valueFrom:
|
||||||
|
|||||||
@@ -210,6 +210,11 @@ postgresql:
|
|||||||
username: "probod"
|
username: "probod"
|
||||||
password: "CHANGE_ME_DB_PASSWORD"
|
password: "CHANGE_ME_DB_PASSWORD"
|
||||||
poolSize: 200
|
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
|
# Uncomment if using TLS with custom CA
|
||||||
# caCertBundle: |
|
# caCertBundle: |
|
||||||
# -----BEGIN CERTIFICATE-----
|
# -----BEGIN CERTIFICATE-----
|
||||||
|
|||||||
@@ -301,6 +301,16 @@ postgresql:
|
|||||||
password: "" # REQUIRED when enabled=false: PostgreSQL password
|
password: "" # REQUIRED when enabled=false: PostgreSQL password
|
||||||
database: probod
|
database: probod
|
||||||
poolSize: 100
|
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
|
# PostgreSQL TLS/SSL configuration
|
||||||
# caBundle: |
|
# caBundle: |
|
||||||
# -----BEGIN CERTIFICATE-----
|
# -----BEGIN CERTIFICATE-----
|
||||||
|
|||||||
@@ -263,8 +263,9 @@ func generateConfig() (string, error) {
|
|||||||
"API_CORS_ALLOWED_ORIGINS": "http://localhost:18080",
|
"API_CORS_ALLOWED_ORIGINS": "http://localhost:18080",
|
||||||
|
|
||||||
// PG.
|
// PG.
|
||||||
"PG_DATABASE": "probod_test",
|
"PG_DATABASE": "probod_test",
|
||||||
"PG_POOL_SIZE": "10",
|
"PG_POOL_SIZE": "10",
|
||||||
|
"PG_MIN_POOL_SIZE": "1",
|
||||||
|
|
||||||
// Auth.
|
// Auth.
|
||||||
"AUTH_COOKIE_SECURE": "false",
|
"AUTH_COOKIE_SECURE": "false",
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -35,7 +35,7 @@ require (
|
|||||||
github.com/vikstrous/dataloadgen v0.0.10
|
github.com/vikstrous/dataloadgen v0.0.10
|
||||||
github.com/yuin/goldmark v1.4.13
|
github.com/yuin/goldmark v1.4.13
|
||||||
go.gearno.de/crypto/uuid v0.1.1-0.20251208105319-3f587312a712
|
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.gearno.de/x/ref v0.0.0-20260216110753-a700c951377c
|
||||||
go.opentelemetry.io/otel v1.43.0
|
go.opentelemetry.io/otel v1.43.0
|
||||||
go.opentelemetry.io/otel/trace v1.43.0
|
go.opentelemetry.io/otel/trace v1.43.0
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -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=
|
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 h1:J5ccbcxFuwxe6Oa9fVi9FqQOo+n17ni4wbl9t4NuEzc=
|
||||||
go.gearno.de/crypto/uuid v0.1.1-0.20251208105319-3f587312a712/go.mod h1:fnIIvKO9QnsyLO3ZJLJT3r8KZv/p0FOeT5eZKilYWXg=
|
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.7.0 h1:0UfrkWmiqpbI4FImWEc/eVBkYD8dMMVshmWtSSiRqJY=
|
||||||
go.gearno.de/kit v0.6.0/go.mod h1:jWrI/mxd0F4GZApL0HgMextcEQoiy2YA1JVamSA/G0E=
|
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 h1:E3Cr9NB8Ry2EsvEG/1eHr7kplP3tEjTf5d56dTX64VQ=
|
||||||
go.gearno.de/x/panicf v0.1.1/go.mod h1:VnB8oF0UefMZcYeD4v+Wk4U5Z1uza7PHLlhT2CbNEbU=
|
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=
|
go.gearno.de/x/ref v0.0.0-20260216110753-a700c951377c h1:rIVWwnNxHYu9aZhHkptXlNYTBJbY4ccaIAYjztVeaDc=
|
||||||
|
|||||||
@@ -81,13 +81,16 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
|
|||||||
ExtraHeaderFields: make(map[string]string),
|
ExtraHeaderFields: make(map[string]string),
|
||||||
},
|
},
|
||||||
Pg: probod.PgConfig{
|
Pg: probod.PgConfig{
|
||||||
Addr: b.getEnvOrDefault("PG_ADDR", "localhost:5432"),
|
Addr: b.getEnvOrDefault("PG_ADDR", "localhost:5432"),
|
||||||
Username: b.getEnvOrDefault("PG_USERNAME", "postgres"),
|
Username: b.getEnvOrDefault("PG_USERNAME", "postgres"),
|
||||||
Password: b.getEnvOrDefault("PG_PASSWORD", "postgres"),
|
Password: b.getEnvOrDefault("PG_PASSWORD", "postgres"),
|
||||||
Database: b.getEnvOrDefault("PG_DATABASE", "probod"),
|
Database: b.getEnvOrDefault("PG_DATABASE", "probod"),
|
||||||
PoolSize: int32(b.getEnvIntOrDefault("PG_POOL_SIZE", 100)),
|
PoolSize: int32(b.getEnvIntOrDefault("PG_POOL_SIZE", 100)),
|
||||||
CACertBundle: pgCACertBundle,
|
MinPoolSize: int32(b.getEnvIntOrDefault("PG_MIN_POOL_SIZE", 10)),
|
||||||
Debug: b.getEnvBoolOrDefault("PG_DEBUG", false),
|
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{
|
Auth: probod.AuthConfig{
|
||||||
DisableSignup: b.getEnvBoolOrDefault("AUTH_DISABLE_SIGNUP", false),
|
DisableSignup: b.getEnvBoolOrDefault("AUTH_DISABLE_SIGNUP", false),
|
||||||
|
|||||||
@@ -131,6 +131,9 @@ func TestBuilder_Build_Defaults(t *testing.T) {
|
|||||||
assert.Equal(t, "postgres", cfg.Probod.Pg.Password)
|
assert.Equal(t, "postgres", cfg.Probod.Pg.Password)
|
||||||
assert.Equal(t, "probod", cfg.Probod.Pg.Database)
|
assert.Equal(t, "probod", cfg.Probod.Pg.Database)
|
||||||
assert.Equal(t, int32(100), cfg.Probod.Pg.PoolSize)
|
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)
|
assert.False(t, cfg.Probod.Pg.Debug)
|
||||||
|
|
||||||
// Auth config
|
// Auth config
|
||||||
@@ -233,6 +236,9 @@ func TestBuilder_Build_CustomValues(t *testing.T) {
|
|||||||
env["PG_PASSWORD"] = "secret123"
|
env["PG_PASSWORD"] = "secret123"
|
||||||
env["PG_DATABASE"] = "probo_prod"
|
env["PG_DATABASE"] = "probo_prod"
|
||||||
env["PG_POOL_SIZE"] = "200"
|
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"
|
env["PG_DEBUG"] = "true"
|
||||||
// Auth
|
// Auth
|
||||||
env["AUTH_DISABLE_SIGNUP"] = "true"
|
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, "secret123", cfg.Probod.Pg.Password)
|
||||||
assert.Equal(t, "probo_prod", cfg.Probod.Pg.Database)
|
assert.Equal(t, "probo_prod", cfg.Probod.Pg.Database)
|
||||||
assert.Equal(t, int32(200), cfg.Probod.Pg.PoolSize)
|
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)
|
assert.True(t, cfg.Probod.Pg.Debug)
|
||||||
// Auth
|
// Auth
|
||||||
assert.True(t, cfg.Probod.Auth.DisableSignup)
|
assert.True(t, cfg.Probod.Auth.DisableSignup)
|
||||||
|
|||||||
@@ -111,11 +111,14 @@ func TestWriteConfig_CompleteConfig(t *testing.T) {
|
|||||||
ExtraHeaderFields: map[string]string{},
|
ExtraHeaderFields: map[string]string{},
|
||||||
},
|
},
|
||||||
Pg: probod.PgConfig{
|
Pg: probod.PgConfig{
|
||||||
Addr: "localhost:5432",
|
Addr: "localhost:5432",
|
||||||
Username: "postgres",
|
Username: "postgres",
|
||||||
Password: "postgres",
|
Password: "postgres",
|
||||||
Database: "probod",
|
Database: "probod",
|
||||||
PoolSize: 100,
|
PoolSize: 100,
|
||||||
|
MinPoolSize: 10,
|
||||||
|
MaxConnIdleTimeSeconds: 1800,
|
||||||
|
MaxConnLifetimeSeconds: 3600,
|
||||||
},
|
},
|
||||||
Connectors: []probod.ConnectorConfig{
|
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.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.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.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)
|
require.Len(t, loaded.Probod.Connectors, 1)
|
||||||
assert.Equal(t, "SLACK", loaded.Probod.Connectors[0].Provider)
|
assert.Equal(t, "SLACK", loaded.Probod.Connectors[0].Provider)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,18 +17,22 @@ package probod
|
|||||||
import (
|
import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
|
"time"
|
||||||
|
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PgConfig struct {
|
type PgConfig struct {
|
||||||
Addr string `json:"addr"`
|
Addr string `json:"addr"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Database string `json:"database"`
|
Database string `json:"database"`
|
||||||
PoolSize int32 `json:"pool-size"`
|
PoolSize int32 `json:"pool-size"`
|
||||||
CACertBundle string `json:"ca-cert-bundle"`
|
MinPoolSize int32 `json:"min-pool-size"`
|
||||||
Debug bool `json:"debug"`
|
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 {
|
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),
|
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 {
|
if cfg.Debug {
|
||||||
opts = append(opts, pg.WithDebug())
|
opts = append(opts, pg.WithDebug())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,11 +152,14 @@ func New() *Implm {
|
|||||||
Addr: "localhost:8080",
|
Addr: "localhost:8080",
|
||||||
},
|
},
|
||||||
Pg: PgConfig{
|
Pg: PgConfig{
|
||||||
Addr: "localhost:5432",
|
Addr: "localhost:5432",
|
||||||
Username: "postgres",
|
Username: "postgres",
|
||||||
Password: "postgres",
|
Password: "postgres",
|
||||||
Database: "probod",
|
Database: "probod",
|
||||||
PoolSize: 100,
|
PoolSize: 100,
|
||||||
|
MinPoolSize: 10,
|
||||||
|
MaxConnIdleTimeSeconds: 1800,
|
||||||
|
MaxConnLifetimeSeconds: 3600,
|
||||||
},
|
},
|
||||||
ChromeDPAddr: "localhost:9222",
|
ChromeDPAddr: "localhost:9222",
|
||||||
Auth: AuthConfig{
|
Auth: AuthConfig{
|
||||||
|
|||||||
Reference in New Issue
Block a user