diff --git a/compute_tools/src/checker.rs b/compute_tools/src/checker.rs index b8413de516..b6a287bdeb 100644 --- a/compute_tools/src/checker.rs +++ b/compute_tools/src/checker.rs @@ -1,12 +1,28 @@ use anyhow::{anyhow, Result}; -use postgres::Client; use tokio_postgres::NoTls; use tracing::{error, instrument}; use crate::compute::ComputeNode; +/// Update timestamp in a row in a special service table to check +/// that we can actually write some data in this particular timeline. +/// Create table if it's missing. #[instrument(skip_all)] -pub fn create_writability_check_data(client: &mut Client) -> Result<()> { +pub async fn check_writability(compute: &ComputeNode) -> Result<()> { + // Connect to the database. + let (client, connection) = tokio_postgres::connect(compute.connstr.as_str(), NoTls).await?; + if client.is_closed() { + return Err(anyhow!("connection to postgres closed")); + } + + // The connection object performs the actual communication with the database, + // so spawn it off to run on its own. + tokio::spawn(async move { + if let Err(e) = connection.await { + error!("connection error: {}", e); + } + }); + let query = " CREATE TABLE IF NOT EXISTS health_check ( id serial primary key, @@ -15,31 +31,15 @@ pub fn create_writability_check_data(client: &mut Client) -> Result<()> { INSERT INTO health_check VALUES (1, now()) ON CONFLICT (id) DO UPDATE SET updated_at = now();"; - let result = client.simple_query(query)?; - if result.len() < 2 { - return Err(anyhow::format_err!("executed {} queries", result.len())); - } - Ok(()) -} - -#[instrument(skip_all)] -pub async fn check_writability(compute: &ComputeNode) -> Result<()> { - let (client, connection) = tokio_postgres::connect(compute.connstr.as_str(), NoTls).await?; - if client.is_closed() { - return Err(anyhow!("connection to postgres closed")); - } - tokio::spawn(async move { - if let Err(e) = connection.await { - error!("connection error: {}", e); - } - }); - - let result = client - .simple_query("UPDATE health_check SET updated_at = now() WHERE id = 1;") - .await?; - - if result.len() != 1 { - return Err(anyhow!("statement can't be executed")); + + let result = client.simple_query(query).await?; + + if result.len() != 2 { + return Err(anyhow::format_err!( + "expected 2 query results, but got {}", + result.len() + )); } + Ok(()) } diff --git a/compute_tools/src/compute.rs b/compute_tools/src/compute.rs index 6ddfcf86c2..51de2b6e0a 100644 --- a/compute_tools/src/compute.rs +++ b/compute_tools/src/compute.rs @@ -32,7 +32,6 @@ use utils::lsn::Lsn; use compute_api::responses::{ComputeMetrics, ComputeStatus}; use compute_api::spec::ComputeSpec; -use crate::checker::create_writability_check_data; use crate::config; use crate::pg_helpers::*; use crate::spec::*; @@ -342,7 +341,6 @@ impl ComputeNode { handle_databases(spec, &mut client)?; handle_role_deletions(spec, self.connstr.as_str(), &mut client)?; handle_grants(spec, self.connstr.as_str(), &mut client)?; - create_writability_check_data(&mut client)?; handle_extensions(spec, &mut client)?; // 'Close' connection diff --git a/compute_tools/src/http/api.rs b/compute_tools/src/http/api.rs index 92d058fbd1..3ca688de69 100644 --- a/compute_tools/src/http/api.rs +++ b/compute_tools/src/http/api.rs @@ -85,7 +85,10 @@ async fn routes(req: Request, compute: &Arc) -> Response Response::new(Body::from("true")), - Err(e) => Response::new(Body::from(e.to_string())), + Err(e) => { + error!("check_writability failed: {}", e); + Response::new(Body::from(e.to_string())) + } } }