actually make readyz useful
This commit is contained in:
parent
d924902cc0
commit
0f17d1cbae
3 changed files with 63 additions and 6 deletions
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "SELECT 1 as running",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "running",
|
||||||
|
"type_info": "Int4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": []
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
null
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "882da6c909603e0916ea9971dafe30de43484ab9c574f6ae0c01331419bf9c31"
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
//! Chir.rs database models
|
//! Chir.rs database models
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
use eyre::{Context, Result};
|
use eyre::{eyre, Context, Result};
|
||||||
use sqlx::{migrate, PgPool};
|
use sqlx::{migrate, query, PgPool};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
@ -13,6 +13,29 @@ pub mod file;
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Database(Arc<PgPool>);
|
pub struct Database(Arc<PgPool>);
|
||||||
|
|
||||||
|
impl Database {
|
||||||
|
/// This function verifies an active connection to the database.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// This function returns an error if the database connection has failed or a timeout of 1s occurred
|
||||||
|
#[instrument]
|
||||||
|
pub async fn ping(&self) -> Result<()> {
|
||||||
|
let fut = async {
|
||||||
|
match query!("SELECT 1 as running").fetch_one(&*self.0).await {
|
||||||
|
Ok(v) if v.running == Some(1) => Ok::<_, eyre::Report>(()),
|
||||||
|
Err(e) => Err(e).context("Checking for readiness"),
|
||||||
|
r => Err(eyre!("Unknown database response: {r:#?}")),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tokio::time::timeout(Duration::from_secs(1), fut)
|
||||||
|
.await
|
||||||
|
.context("Awaiting a ping")??;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Opens the database
|
/// Opens the database
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{MatchedPath, Request, State},
|
extract::{MatchedPath, Request, State},
|
||||||
http::Response,
|
http::{Response, StatusCode},
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
routing::get,
|
routing::get,
|
||||||
Router,
|
Router,
|
||||||
|
@ -17,7 +17,7 @@ use chir_rs_http_api::{axum::bincode::Bincode, readiness::ReadyState};
|
||||||
use eyre::{Context, Result};
|
use eyre::{Context, Result};
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
use tracing::{info, info_span};
|
use tracing::{error, info, info_span};
|
||||||
|
|
||||||
/// Application state
|
/// Application state
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -48,7 +48,21 @@ pub async fn main(cfg: Arc<ChirRs>, db: Database, castore: CaStore) -> Result<()
|
||||||
let (prometheus_layer, metric_handle) = PrometheusMetricLayer::pair();
|
let (prometheus_layer, metric_handle) = PrometheusMetricLayer::pair();
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
// Routes here
|
// Routes here
|
||||||
.route("/.api/readyz", get(|| async { Bincode(ReadyState::Ready) }))
|
.route(
|
||||||
|
"/.api/readyz",
|
||||||
|
get(|State(state): State<AppState>| async move {
|
||||||
|
match state.db.ping().await {
|
||||||
|
Ok(()) => (StatusCode::OK, Bincode(ReadyState::Ready)),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Database is not responding: {e:?}");
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Bincode(ReadyState::NotReady),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/.api/metrics",
|
"/.api/metrics",
|
||||||
get(|| async move { metric_handle.render() }),
|
get(|| async move { metric_handle.render() }),
|
||||||
|
|
Loading…
Reference in a new issue