Skip to main content

ironflow_ops_postgres/admin/
health.rs

1//! Health check operation.
2
3use async_trait::async_trait;
4use ironflow_core::error::OperationError;
5use ironflow_core::operation::{Operation, OperationContext, TypedOperation};
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8use sqlx::PgPool;
9
10use crate::helpers::{pg_error, to_value};
11
12/// Output of [`HealthCheck`].
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct HealthCheckOutput {
15    /// Always `true` when the check succeeds.
16    pub healthy: bool,
17}
18
19/// Verify database connectivity with `SELECT 1`.
20///
21/// # Examples
22///
23/// ```no_run
24/// use ironflow_ops_postgres::admin::health::HealthCheck;
25/// use ironflow_core::operation::Operation;
26///
27/// # fn example(pool: sqlx::PgPool) {
28/// let op = HealthCheck::new(pool);
29/// assert_eq!(op.kind(), "postgres");
30/// # }
31/// ```
32pub struct HealthCheck {
33    pool: PgPool,
34}
35
36impl HealthCheck {
37    /// Create a new health-check operation.
38    pub fn new(pool: PgPool) -> Self {
39        Self { pool }
40    }
41
42    /// Execute and return a typed result.
43    ///
44    /// # Errors
45    ///
46    /// Returns [`OperationError::External`] if the database is unreachable.
47    pub async fn run(&self, _ctx: &OperationContext) -> Result<HealthCheckOutput, OperationError> {
48        sqlx::query("SELECT 1")
49            .fetch_one(&self.pool)
50            .await
51            .map_err(pg_error)?;
52        Ok(HealthCheckOutput { healthy: true })
53    }
54}
55
56#[async_trait]
57impl Operation for HealthCheck {
58    fn kind(&self) -> &str {
59        "postgres"
60    }
61    async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
62        to_value(&self.run(ctx).await?)
63    }
64}
65
66impl TypedOperation for HealthCheck {
67    type Output = HealthCheckOutput;
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[tokio::test]
75    async fn kind() {
76        let pool = PgPool::connect_lazy("postgres://localhost/test").unwrap();
77        let op = HealthCheck::new(pool);
78        assert_eq!(op.kind(), "postgres");
79    }
80}