Skip to content

Commit 173609c

Browse files
committed
Allow setting idle_timeout for server connections.
In postgres, you can specify an `idle_session_timeout` which will close sessions idling for that amount of time. If a session is closed because of a timeout, PgCat will erroneously mark the server as unhealthy as the next health check will return an error because the connection was drop, if no health check is to be executed, it will simply fail trying to send the query to the server for the same reason, the conn was drop. Given that bb8 allows configuring an idle_timeout for pools, it would be nice to allow setting this parameter in the config file, this way you can set it to something shorter than the server one. Also, server pool will be kept smaller in moments of less traffic. Actually, currently this value is set as its default in bb8, which is 10 minutes. This changes allows setting the parameter using the config file. It can be set both globally and per pool. When creating the pool, if the pool don't have it defined, global value is used.
1 parent b9b5635 commit 173609c

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

pgcat.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ prometheus_exporter_port = 9930
2020
# How long to wait before aborting a server connection (ms).
2121
connect_timeout = 5000
2222

23+
# How long an idle connection with a server is left open (ms).
24+
idle_timeout = 30000
25+
2326
# How much time to give the health check query to return with a result (ms).
2427
healthcheck_timeout = 1000
2528

@@ -92,6 +95,9 @@ sharding_function = "pg_bigint_hash"
9295
# Automatically parse this from queries and route queries to the right shard!
9396
automatic_sharding_key = "id"
9497

98+
# Idle timeout can be overwritten in the pool
99+
idle_timeout = 40000
100+
95101
# Credentials for users that may connect to this cluster
96102
[pools.sharded_db.users.0]
97103
username = "sharding_user"

src/config.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ pub struct General {
157157
#[serde(default = "General::default_connect_timeout")]
158158
pub connect_timeout: u64,
159159

160+
#[serde(default = "General::default_idle_timeout")]
161+
pub idle_timeout: u64,
162+
160163
#[serde(default)] // False
161164
pub log_client_connections: bool,
162165

@@ -197,6 +200,10 @@ impl General {
197200
1000
198201
}
199202

203+
pub fn default_idle_timeout() -> u64 {
204+
60000 // 10 minutes
205+
}
206+
200207
pub fn default_shutdown_timeout() -> u64 {
201208
60000
202209
}
@@ -222,6 +229,7 @@ impl Default for General {
222229
enable_prometheus_exporter: Some(false),
223230
prometheus_exporter_port: 9930,
224231
connect_timeout: General::default_connect_timeout(),
232+
idle_timeout: General::default_idle_timeout(),
225233
shutdown_timeout: Self::default_shutdown_timeout(),
226234
healthcheck_timeout: Self::default_healthcheck_timeout(),
227235
healthcheck_delay: Self::default_healthcheck_delay(),
@@ -273,6 +281,8 @@ pub struct Pool {
273281

274282
pub connect_timeout: Option<u64>,
275283

284+
pub idle_timeout: Option<u64>,
285+
276286
pub sharding_function: ShardingFunction,
277287

278288
#[serde(default = "Pool::default_automatic_sharding_key")]
@@ -335,6 +345,7 @@ impl Default for Pool {
335345
sharding_function: ShardingFunction::PgBigintHash,
336346
automatic_sharding_key: None,
337347
connect_timeout: None,
348+
idle_timeout: None,
338349
}
339350
}
340351
}
@@ -496,6 +507,10 @@ impl From<&Config> for std::collections::HashMap<String, String> {
496507
"connect_timeout".to_string(),
497508
config.general.connect_timeout.to_string(),
498509
),
510+
(
511+
"idle_timeout".to_string(),
512+
config.general.idle_timeout.to_string(),
513+
),
499514
(
500515
"healthcheck_timeout".to_string(),
501516
config.general.healthcheck_timeout.to_string(),
@@ -525,6 +540,7 @@ impl Config {
525540
self.general.healthcheck_timeout
526541
);
527542
info!("Connection timeout: {}ms", self.general.connect_timeout);
543+
info!("Idle timeout: {}ms", self.general.idle_timeout);
528544
info!(
529545
"Log client connections: {}",
530546
self.general.log_client_connections
@@ -578,6 +594,11 @@ impl Config {
578594
"[pool: {}] Connection timeout: {}ms",
579595
pool_name, connect_timeout
580596
);
597+
let idle_timeout = match pool_config.idle_timeout {
598+
Some(idle_timeout) => idle_timeout,
599+
None => self.general.idle_timeout,
600+
};
601+
info!("[pool: {}] Idle timeout: {}ms", pool_name, idle_timeout);
581602
info!(
582603
"[pool: {}] Sharding function: {}",
583604
pool_name,
@@ -732,8 +753,10 @@ mod test {
732753
assert_eq!(get_config().path, "pgcat.toml".to_string());
733754

734755
assert_eq!(get_config().general.ban_time, 60);
756+
assert_eq!(get_config().general.idle_timeout, 30000);
735757
assert_eq!(get_config().pools.len(), 2);
736758
assert_eq!(get_config().pools["sharded_db"].shards.len(), 3);
759+
assert_eq!(get_config().pools["sharded_db"].idle_timeout, Some(40000));
737760
assert_eq!(get_config().pools["simple_db"].shards.len(), 1);
738761
assert_eq!(get_config().pools["sharded_db"].users.len(), 2);
739762
assert_eq!(get_config().pools["simple_db"].users.len(), 1);

src/pool.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,15 @@ impl ConnectionPool {
224224
None => config.general.connect_timeout,
225225
};
226226

227+
let idle_timeout = match pool_config.idle_timeout {
228+
Some(idle_timeout) => idle_timeout,
229+
None => config.general.idle_timeout,
230+
};
231+
227232
let pool = Pool::builder()
228233
.max_size(user.pool_size)
229234
.connection_timeout(std::time::Duration::from_millis(connect_timeout))
235+
.idle_timeout(Some(std::time::Duration::from_millis(idle_timeout)))
230236
.test_on_check_out(false)
231237
.build(manager)
232238
.await

0 commit comments

Comments
 (0)