darkwing/server/services/
status_services.rsuse anyhow::Context;
use mockall::automock;
use redis::Commands;
use sqlx::query;
use std::sync::Arc;
use tracing::info;
use async_trait::async_trait;
use crate::{
cache::Cache,
config::DarkwingConfig,
database::Database,
server::{
dtos::health_dto::{DatabaseStatus, HealthResponse, ServiceStatuses},
error::AppResult,
},
};
pub type DynStatusService = Arc<dyn StatusServiceTrait + Send + Sync>;
#[automock]
#[async_trait]
pub trait StatusServiceTrait {
async fn get_health_status(
&self,
s3_status: ServiceStatuses,
) -> AppResult<HealthResponse>;
}
#[derive(Clone)]
pub struct StatusService {
config: Arc<DarkwingConfig>,
database: Arc<Database>,
cache: Arc<Cache>,
}
impl StatusService {
pub fn new(
database: Arc<Database>,
cache: Arc<Cache>,
config: Arc<DarkwingConfig>,
) -> Self {
Self {
database,
cache,
config,
}
}
}
#[async_trait]
impl StatusServiceTrait for StatusService {
async fn get_health_status(
&self,
s3_status: ServiceStatuses,
) -> AppResult<HealthResponse> {
info!("Checking health status");
let main_mysql = query("SELECT true")
.fetch_one(&self.database.pool)
.await
.is_ok();
let redis_cache = self
.cache
.pool
.get_timeout(self.config.redis_timeout())
.context("Failed to get Redis connection")?
.set::<_, _, ()>("StatusServiceTest", "test")
.is_ok();
let db_status = DatabaseStatus {
main_mysql,
redis_cache,
};
Ok(HealthResponse::new(Some(db_status), Some(s3_status)))
}
}