Skip to content

Commit 0428df0

Browse files
authored
feat (breaking): user settings take precedence over database settings in pgdog.toml (#781)
User is more specific, and you have multiple users per database, so it's kinda surprising that the database pool size takes precedence. Fix that. This one caught us out, I'm assuming it's not intentional? if so, it's a bit confusing and maybe the docs should outline that? (I still think it should be changed though.)
1 parent bc111ba commit 0428df0

1 file changed

Lines changed: 53 additions & 20 deletions

File tree

pgdog/src/backend/pool/config.rs

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -99,46 +99,42 @@ impl Config {
9999
pub fn new(general: &General, database: &Database, user: &User, is_only_replica: bool) -> Self {
100100
Self {
101101
inner: pgdog_stats::Config {
102-
min: database
102+
min: user
103103
.min_pool_size
104-
.unwrap_or(user.min_pool_size.unwrap_or(general.min_pool_size)),
105-
max: database
104+
.unwrap_or(database.min_pool_size.unwrap_or(general.min_pool_size)),
105+
max: user
106106
.pool_size
107-
.unwrap_or(user.pool_size.unwrap_or(general.default_pool_size)),
107+
.unwrap_or(database.pool_size.unwrap_or(general.default_pool_size)),
108108
max_age: Duration::from_millis(
109-
database
110-
.server_lifetime
111-
.unwrap_or(user.server_lifetime.unwrap_or(general.server_lifetime)),
109+
user.server_lifetime
110+
.unwrap_or(database.server_lifetime.unwrap_or(general.server_lifetime)),
112111
),
113112
healthcheck_interval: Duration::from_millis(general.healthcheck_interval),
114113
idle_healthcheck_interval: Duration::from_millis(general.idle_healthcheck_interval),
115114
idle_healthcheck_delay: Duration::from_millis(general.idle_healthcheck_delay),
116115
healthcheck_timeout: Duration::from_millis(general.healthcheck_timeout),
117116
ban_timeout: Duration::from_millis(general.ban_timeout),
118117
rollback_timeout: Duration::from_millis(general.rollback_timeout),
119-
statement_timeout: if let Some(statement_timeout) = database.statement_timeout {
120-
Some(statement_timeout)
121-
} else {
122-
user.statement_timeout
123-
}
124-
.map(Duration::from_millis),
118+
statement_timeout: user
119+
.statement_timeout
120+
.or(database.statement_timeout)
121+
.map(Duration::from_millis),
125122
replication_mode: user.replication_mode,
126-
pooler_mode: database
123+
pooler_mode: user
127124
.pooler_mode
128-
.unwrap_or(user.pooler_mode.unwrap_or(general.pooler_mode)),
125+
.unwrap_or(database.pooler_mode.unwrap_or(general.pooler_mode)),
129126
connect_timeout: Duration::from_millis(general.connect_timeout),
130127
connect_attempts: general.connect_attempts,
131128
connect_attempt_delay: general.connect_attempt_delay(),
132129
query_timeout: Duration::from_millis(general.query_timeout),
133130
checkout_timeout: Duration::from_millis(general.checkout_timeout),
134131
idle_timeout: Duration::from_millis(
135-
database
136-
.idle_timeout
137-
.unwrap_or(user.idle_timeout.unwrap_or(general.idle_timeout)),
132+
user.idle_timeout
133+
.unwrap_or(database.idle_timeout.unwrap_or(general.idle_timeout)),
138134
),
139-
read_only: database
135+
read_only: user
140136
.read_only
141-
.unwrap_or(user.read_only.unwrap_or_default()),
137+
.unwrap_or(database.read_only.unwrap_or_default()),
142138
prepared_statements_limit: general.prepared_statements_limit,
143139
stats_period: Duration::from_millis(general.stats_period),
144140
bannable: !is_only_replica,
@@ -164,6 +160,7 @@ impl Default for Config {
164160
#[cfg(test)]
165161
mod test {
166162
use super::*;
163+
use pgdog_config::PoolerMode;
167164

168165
fn create_database(role: Role) -> Database {
169166
Database {
@@ -186,6 +183,42 @@ mod test {
186183
assert!(config.role_detection);
187184
}
188185

186+
#[test]
187+
fn test_user_takes_precedence_over_database() {
188+
let general = General::default();
189+
let user = User {
190+
pool_size: Some(5),
191+
min_pool_size: Some(5),
192+
server_lifetime: Some(5),
193+
statement_timeout: Some(5),
194+
pooler_mode: Some(PoolerMode::Session),
195+
idle_timeout: Some(5),
196+
read_only: Some(true),
197+
..Default::default()
198+
};
199+
200+
let database = Database {
201+
pool_size: Some(10),
202+
min_pool_size: Some(10),
203+
server_lifetime: Some(10),
204+
statement_timeout: Some(10),
205+
pooler_mode: Some(PoolerMode::Transaction),
206+
idle_timeout: Some(10),
207+
read_only: Some(false),
208+
..Default::default()
209+
};
210+
211+
let config = Config::new(&general, &database, &user, false);
212+
213+
assert_eq!(5, config.max);
214+
assert_eq!(5, config.min);
215+
assert_eq!(Duration::from_millis(5), config.max_age);
216+
assert_eq!(Some(Duration::from_millis(5)), config.statement_timeout);
217+
assert_eq!(PoolerMode::Session, config.pooler_mode);
218+
assert_eq!(Duration::from_millis(5), config.idle_timeout);
219+
assert_eq!(true, config.read_only);
220+
}
221+
189222
#[test]
190223
fn test_role_primary_disables_role_detection() {
191224
let general = General::default();

0 commit comments

Comments
 (0)