Adds SHUTDOWN command as alternate option to sending SIGINT (#331)

* Adds SHUTDOWN command to PgCat as alternate option to sending SIGINT

* Check if we're already in SHUTDOWN sequence

* Send signal directly from shutdown instead of using channel

* Add tests

* trigger build

* Lowercase response and boolean change

* Update tests

* Fix tests

* typo
This commit is contained in:
zainkabani
2023-02-27 01:16:30 -05:00
committed by GitHub
parent 75a7d4409a
commit eb8cfdb1f1
5 changed files with 327 additions and 172 deletions

View File

@@ -1,6 +1,8 @@
/// Admin database.
use bytes::{Buf, BufMut, BytesMut};
use log::{info, trace};
use log::{error, info, trace};
use nix::sys::signal::{self, Signal};
use nix::unistd::Pid;
use std::collections::HashMap;
use tokio::time::Instant;
@@ -67,6 +69,10 @@ where
trace!("RESUME");
resume(stream, query_parts[1]).await
}
"SHUTDOWN" => {
trace!("SHUTDOWN");
shutdown(stream).await
}
"SHOW" => match query_parts[1].to_ascii_uppercase().as_str() {
"CONFIG" => {
trace!("SHOW CONFIG");
@@ -671,6 +677,34 @@ where
}
}
/// Send response packets for shutdown.
async fn shutdown<T>(stream: &mut T) -> Result<(), Error>
where
T: tokio::io::AsyncWrite + std::marker::Unpin,
{
let mut res = BytesMut::new();
res.put(row_description(&vec![("success", DataType::Text)]));
let mut shutdown_success = "t";
let pid = std::process::id();
if signal::kill(Pid::from_raw(pid.try_into().unwrap()), Signal::SIGINT).is_err() {
error!("Unable to send SIGINT to PID: {}", pid);
shutdown_success = "f";
}
res.put(data_row(&vec![shutdown_success.to_string()]));
res.put(command_complete("SHUTDOWN"));
res.put_u8(b'Z');
res.put_i32(5);
res.put_u8(b'I');
write_all_half(stream, &res).await
}
/// Show Users.
async fn show_users<T>(stream: &mut T) -> Result<(), Error>
where