Skip to content

Commit 26f75f8

Browse files
authored
admin RELOAD (#49)
* admin RELOAD * test
1 parent 99d65fc commit 26f75f8

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

.circleci/run_tests.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ sed -i 's/pool_mode = "transaction"/pool_mode = "session"/' pgcat.toml
8686
# Reload config test
8787
kill -SIGHUP $(pgrep pgcat)
8888

89+
# Reload again with the admin database
90+
psql -h 127.0.0.1 -p 6432 -d pgbouncer -c 'RELOAD' > /dev/null
91+
8992
# Prepared statements that will only work in session mode
9093
pgbench -h 127.0.0.1 -p 6432 -t 500 -c 2 --protocol prepared
9194

src/admin.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use bytes::{Buf, BufMut, BytesMut};
2-
use log::trace;
2+
use log::{info, trace};
33
use tokio::net::tcp::OwnedWriteHalf;
44

5+
use crate::config::{get_config, parse};
56
use crate::constants::{OID_NUMERIC, OID_TEXT};
67
use crate::errors::Error;
78
use crate::messages::write_all_half;
@@ -23,11 +24,43 @@ pub async fn handle_admin(stream: &mut OwnedWriteHalf, mut query: BytesMut) -> R
2324
if query.starts_with("SHOW STATS") {
2425
trace!("SHOW STATS");
2526
show_stats(stream).await
27+
} else if query.starts_with("RELOAD") {
28+
trace!("RELOAD");
29+
reload(stream).await
2630
} else {
2731
Err(Error::ProtocolSyncError)
2832
}
2933
}
3034

35+
/// RELOAD
36+
pub async fn reload(stream: &mut OwnedWriteHalf) -> Result<(), Error> {
37+
info!("Reloading config");
38+
39+
let config = get_config();
40+
let path = config.path.clone().unwrap();
41+
42+
parse(&path).await?;
43+
44+
let config = get_config();
45+
46+
config.show();
47+
48+
let mut res = BytesMut::new();
49+
50+
// CommandComplete
51+
let command_complete = BytesMut::from(&"RELOAD\0"[..]);
52+
res.put_u8(b'C');
53+
res.put_i32(command_complete.len() as i32 + 4);
54+
res.put(command_complete);
55+
56+
// ReadyForQuery
57+
res.put_u8(b'Z');
58+
res.put_i32(5);
59+
res.put_u8(b'I');
60+
61+
write_all_half(stream, res).await
62+
}
63+
3164
/// SHOW STATS
3265
pub async fn show_stats(stream: &mut OwnedWriteHalf) -> Result<(), Error> {
3366
let columns = [

src/config.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ impl Default for QueryRouter {
134134

135135
#[derive(Deserialize, Debug, Clone)]
136136
pub struct Config {
137+
pub path: Option<String>,
137138
pub general: General,
138139
pub user: User,
139140
pub shards: HashMap<String, Shard>,
@@ -143,6 +144,7 @@ pub struct Config {
143144
impl Default for Config {
144145
fn default() -> Config {
145146
Config {
147+
path: Some(String::from("pgcat.toml")),
146148
general: General::default(),
147149
user: User::default(),
148150
shards: HashMap::from([(String::from("1"), Shard::default())]),
@@ -189,7 +191,7 @@ pub async fn parse(path: &str) -> Result<(), Error> {
189191
}
190192
};
191193

192-
let config: Config = match toml::from_str(&contents) {
194+
let mut config: Config = match toml::from_str(&contents) {
193195
Ok(config) => config,
194196
Err(err) => {
195197
error!("Could not parse config file: {}", err.to_string());
@@ -279,6 +281,8 @@ pub async fn parse(path: &str) -> Result<(), Error> {
279281
}
280282
};
281283

284+
config.path = Some(path.to_string());
285+
282286
CONFIG.store(Arc::new(config.clone()));
283287

284288
Ok(())
@@ -296,5 +300,6 @@ mod test {
296300
assert_eq!(get_config().shards["1"].servers[0].0, "127.0.0.1");
297301
assert_eq!(get_config().shards["0"].servers[0].2, "primary");
298302
assert_eq!(get_config().query_router.default_role, "any");
303+
assert_eq!(get_config().path, Some("pgcat.toml".to_string()));
299304
}
300305
}

0 commit comments

Comments
 (0)