diff --git a/docs/config.md b/docs/config.md index 188dfbe9..ff47a7fb 100644 --- a/docs/config.md +++ b/docs/config.md @@ -163,7 +163,7 @@ You can tune the connection pool by appending query parameters to the database U | Parameter | Default | Description | |---|---|---| -| `pool_max_conns` | 25 | Maximum number of open connections to the database | +| `pool_max_conns` | 10 | Maximum number of open connections to the database | | `pool_max_idle_conns` | - | Maximum number of idle connections in the pool | | `pool_conn_max_lifetime` | - | Maximum amount of time a connection may be reused (Go duration, e.g. `5m`, `1h`) | | `pool_conn_max_idle_time` | - | Maximum amount of time a connection may be idle (Go duration, e.g. `30s`, `5m`) | diff --git a/message/store_postgres_test.go b/message/store_postgres_test.go index ebe60c70..951d571f 100644 --- a/message/store_postgres_test.go +++ b/message/store_postgres_test.go @@ -21,6 +21,9 @@ func newTestPostgresStore(t *testing.T) message.Store { u, err := url.Parse(dsn) require.Nil(t, err) q := u.Query() + q.Set("pool_max_conns", "2") + u.RawQuery = q.Encode() + dsn = u.String() q.Set("search_path", schema) u.RawQuery = q.Encode() schemaDSN := u.String() diff --git a/postgres/postgres.go b/postgres/postgres.go index 94913f58..437b413e 100644 --- a/postgres/postgres.go +++ b/postgres/postgres.go @@ -10,10 +10,10 @@ import ( _ "github.com/jackc/pgx/v5/stdlib" // PostgreSQL driver ) -const defaultMaxOpenConns = 25 +const defaultMaxOpenConns = 10 // OpenDB opens a PostgreSQL database connection pool from a DSN string. It supports custom -// query parameters for pool configuration: pool_max_conns (default 25), pool_max_idle_conns, +// query parameters for pool configuration: pool_max_conns (default 10), pool_max_idle_conns, // pool_conn_max_lifetime, and pool_conn_max_idle_time. These parameters are stripped from // the DSN before passing it to the driver. func OpenDB(dsn string) (*sql.DB, error) { @@ -54,7 +54,7 @@ func OpenDB(dsn string) (*sql.DB, error) { db.SetConnMaxIdleTime(connMaxIdleTime) } if err := db.Ping(); err != nil { - return nil, err + return nil, fmt.Errorf("ping failed: %w", err) } return db, nil } diff --git a/server/server.go b/server/server.go index 243a5094..8da588ff 100644 --- a/server/server.go +++ b/server/server.go @@ -425,6 +425,9 @@ func (s *Server) closeDatabases() { if s.webPush != nil { s.webPush.Close() } + if s.db != nil { + s.db.Close() + } } // handle is the main entry point for all HTTP requests diff --git a/server/server.yml b/server/server.yml index 28675806..b3f5e11e 100644 --- a/server/server.yml +++ b/server/server.yml @@ -43,7 +43,7 @@ # "auth-file", and "web-push-file" options are not required. # # You can append connection pool parameters as query parameters: -# pool_max_conns=25 - Maximum number of open connections (default: 25) +# pool_max_conns=10 - Maximum number of open connections (default: 10) # pool_max_idle_conns=N - Maximum number of idle connections # pool_conn_max_lifetime=5m - Maximum lifetime of a connection (Go duration) # pool_conn_max_idle_time=1m - Maximum idle time of a connection (Go duration) diff --git a/server/server_test.go b/server/server_test.go index 88bc1d5a..b1eacc8f 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -4134,14 +4134,17 @@ func forEachBackend(t *testing.T, f func(t *testing.T, databaseURL string)) { t.Skip("NTFY_TEST_DATABASE_URL not set") } schema := fmt.Sprintf("test_%s", util.RandomString(10)) - setupDB, err := postgres.OpenDB(dsn) - require.Nil(t, err) - _, err = setupDB.Exec(fmt.Sprintf("CREATE SCHEMA %s", schema)) - require.Nil(t, err) - require.Nil(t, setupDB.Close()) u, err := url.Parse(dsn) require.Nil(t, err) q := u.Query() + q.Set("pool_max_conns", "2") + u.RawQuery = q.Encode() + dsn = u.String() + setupDB, err := postgres.OpenDB(dsn) + require.Nil(t, err, "failed to open postgres: %s", err) + _, err = setupDB.Exec(fmt.Sprintf("CREATE SCHEMA %s", schema)) + require.Nil(t, err) + require.Nil(t, setupDB.Close()) q.Set("search_path", schema) u.RawQuery = q.Encode() schemaDSN := u.String() @@ -4188,6 +4191,7 @@ func newTestConfigWithAuthFile(t *testing.T, databaseURL string) *Config { func newTestServer(t *testing.T, config *Config) *Server { server, err := New(config) require.Nil(t, err) + t.Cleanup(server.closeDatabases) return server } diff --git a/user/manager_test.go b/user/manager_test.go index 133c7b05..139eecb3 100644 --- a/user/manager_test.go +++ b/user/manager_test.go @@ -39,14 +39,17 @@ func forEachBackend(t *testing.T, f func(t *testing.T, newStore newStoreFunc)) { t.Skip("NTFY_TEST_DATABASE_URL not set") } schema := fmt.Sprintf("test_%s", util.RandomString(10)) + u, err := url.Parse(dsn) + require.Nil(t, err) + q := u.Query() + q.Set("pool_max_conns", "2") + u.RawQuery = q.Encode() + dsn = u.String() setupDB, err := postgres.OpenDB(dsn) require.Nil(t, err) _, err = setupDB.Exec(fmt.Sprintf("CREATE SCHEMA %s", schema)) require.Nil(t, err) require.Nil(t, setupDB.Close()) - u, err := url.Parse(dsn) - require.Nil(t, err) - q := u.Query() q.Set("search_path", schema) u.RawQuery = q.Encode() schemaDSN := u.String() diff --git a/user/store_postgres_test.go b/user/store_postgres_test.go index ea222539..fafa62e9 100644 --- a/user/store_postgres_test.go +++ b/user/store_postgres_test.go @@ -21,6 +21,9 @@ func newTestPostgresStore(t *testing.T) user.Store { u, err := url.Parse(dsn) require.Nil(t, err) q := u.Query() + q.Set("pool_max_conns", "2") + u.RawQuery = q.Encode() + dsn = u.String() q.Set("search_path", schema) u.RawQuery = q.Encode() schemaDSN := u.String() diff --git a/webpush/store_postgres_test.go b/webpush/store_postgres_test.go index bacd8163..bdcc7a8e 100644 --- a/webpush/store_postgres_test.go +++ b/webpush/store_postgres_test.go @@ -21,6 +21,9 @@ func newTestPostgresStore(t *testing.T) webpush.Store { u, err := url.Parse(dsn) require.Nil(t, err) q := u.Query() + q.Set("pool_max_conns", "2") + u.RawQuery = q.Encode() + dsn = u.String() q.Set("search_path", schema) u.RawQuery = q.Encode() schemaDSN := u.String()