Line data Source code
1 : use anyhow::{Context, anyhow};
2 :
3 : // Run `/usr/local/bin/pg_isready -p {port}`
4 : // Check the connectivity of PG
5 : // Success means PG is listening on the port and accepting connections
6 : // Note that PG does not need to authenticate the connection, nor reserve a connection quota for it.
7 : // See https://www.postgresql.org/docs/current/app-pg-isready.html
8 0 : pub fn pg_isready(bin: &str, port: u16) -> anyhow::Result<()> {
9 0 : let child_result = std::process::Command::new(bin)
10 0 : .arg("-p")
11 0 : .arg(port.to_string())
12 0 : .spawn();
13 :
14 0 : child_result
15 0 : .context("spawn() failed")
16 0 : .and_then(|mut child| child.wait().context("wait() failed"))
17 0 : .and_then(|status| match status.success() {
18 0 : true => Ok(()),
19 0 : false => Err(anyhow!("process exited with {status}")),
20 0 : })
21 : // wrap any prior error with the overall context that we couldn't run the command
22 0 : .with_context(|| format!("could not run `{bin} --port {port}`"))
23 0 : }
24 :
25 : // It's safe to assume pg_isready is under the same directory with postgres,
26 : // because it is a PG util bin installed along with postgres
27 0 : pub fn get_pg_isready_bin(pgbin: &str) -> String {
28 0 : let split = pgbin.split("/").collect::<Vec<&str>>();
29 0 : split[0..split.len() - 1].join("/") + "/pg_isready"
30 0 : }
|