Skip to content
Snippets Groups Projects
Unverified Commit aafbaa36 authored by Stephan Renatus's avatar Stephan Renatus Committed by GitHub
Browse files

Merge pull request #1357 from srenatus/sr/issue-1354

postgres: expose database/sql tunables

Fixes #1354.

I've not had a need for MaxIdleConns and ConnMaxLifetime myself, but it felt weird to only expose of the three settings.
parents 60264d44 73fdf4f7
No related branches found
No related tags found
No related merge requests found
...@@ -18,10 +18,14 @@ func TestUnmarshalConfig(t *testing.T) { ...@@ -18,10 +18,14 @@ func TestUnmarshalConfig(t *testing.T) {
rawConfig := []byte(` rawConfig := []byte(`
issuer: http://127.0.0.1:5556/dex issuer: http://127.0.0.1:5556/dex
storage: storage:
type: sqlite3 type: postgres
config: config:
file: examples/dex.db host: 10.0.0.1
port: 65432
maxOpenConns: 5
maxIdleConns: 3
connMaxLifetime: 30
connectionTimeout: 3
web: web:
http: 127.0.0.1:5556 http: 127.0.0.1:5556
staticClients: staticClients:
...@@ -69,9 +73,14 @@ logger: ...@@ -69,9 +73,14 @@ logger:
want := Config{ want := Config{
Issuer: "http://127.0.0.1:5556/dex", Issuer: "http://127.0.0.1:5556/dex",
Storage: Storage{ Storage: Storage{
Type: "sqlite3", Type: "postgres",
Config: &sql.SQLite3{ Config: &sql.Postgres{
File: "examples/dex.db", Host: "10.0.0.1",
Port: 65432,
MaxOpenConns: 5,
MaxIdleConns: 3,
ConnMaxLifetime: 30,
ConnectionTimeout: 3,
}, },
}, },
Web: Web{ Web: Web{
......
...@@ -7,6 +7,7 @@ import ( ...@@ -7,6 +7,7 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/lib/pq" "github.com/lib/pq"
sqlite3 "github.com/mattn/go-sqlite3" sqlite3 "github.com/mattn/go-sqlite3"
...@@ -88,6 +89,13 @@ type Postgres struct { ...@@ -88,6 +89,13 @@ type Postgres struct {
SSL PostgresSSL `json:"ssl" yaml:"ssl"` SSL PostgresSSL `json:"ssl" yaml:"ssl"`
ConnectionTimeout int // Seconds ConnectionTimeout int // Seconds
// database/sql tunables, see
// https://golang.org/pkg/database/sql/#DB.SetConnMaxLifetime and below
// Note: defaults will be set if these are 0
MaxOpenConns int // default: 5
MaxIdleConns int // default: 5
ConnMaxLifetime int // Seconds, default: not set
} }
// Open creates a new storage implementation backed by Postgres. // Open creates a new storage implementation backed by Postgres.
...@@ -177,6 +185,23 @@ func (p *Postgres) open(logger logrus.FieldLogger, dataSourceName string) (*conn ...@@ -177,6 +185,23 @@ func (p *Postgres) open(logger logrus.FieldLogger, dataSourceName string) (*conn
return nil, err return nil, err
} }
// set database/sql tunables if configured
if p.ConnMaxLifetime != 0 {
db.SetConnMaxLifetime(time.Duration(p.ConnMaxLifetime) * time.Second)
}
if p.MaxIdleConns == 0 {
db.SetMaxIdleConns(5)
} else {
db.SetMaxIdleConns(p.MaxIdleConns)
}
if p.MaxOpenConns == 0 {
db.SetMaxOpenConns(5)
} else {
db.SetMaxOpenConns(p.MaxOpenConns)
}
errCheck := func(err error) bool { errCheck := func(err error) bool {
sqlErr, ok := err.(*pq.Error) sqlErr, ok := err.(*pq.Error)
if !ok { if !ok {
......
// +build go1.11
package sql
import (
"os"
"testing"
)
func TestPostgresTunables(t *testing.T) {
host := os.Getenv(testPostgresEnv)
if host == "" {
t.Skipf("test environment variable %q not set, skipping", testPostgresEnv)
}
baseCfg := &Postgres{
Database: getenv("DEX_POSTGRES_DATABASE", "postgres"),
User: getenv("DEX_POSTGRES_USER", "postgres"),
Password: getenv("DEX_POSTGRES_PASSWORD", "postgres"),
Host: host,
SSL: PostgresSSL{
Mode: sslDisable, // Postgres container doesn't support SSL.
}}
t.Run("with nothing set, uses defaults", func(t *testing.T) {
cfg := *baseCfg
c, err := cfg.open(logger, cfg.createDataSourceName())
if err != nil {
t.Fatalf("error opening connector: %s", err.Error())
}
defer c.db.Close()
if m := c.db.Stats().MaxOpenConnections; m != 5 {
t.Errorf("expected MaxOpenConnections to have its default (5), got %d", m)
}
})
t.Run("with something set, uses that", func(t *testing.T) {
cfg := *baseCfg
cfg.MaxOpenConns = 101
c, err := cfg.open(logger, cfg.createDataSourceName())
if err != nil {
t.Fatalf("error opening connector: %s", err.Error())
}
defer c.db.Close()
if m := c.db.Stats().MaxOpenConnections; m != 101 {
t.Errorf("expected MaxOpenConnections to be set to 101, got %d", m)
}
})
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment