use crate::Result;
use async_std::task;
use crate::types::ReadyIndicator;
use log::{info, warn};
use stop_token::{future::FutureExt, StopToken};
use tide::{Middleware, Next, Request, Response};
#[derive(Clone)]
pub struct State {
ready_indicator: ReadyIndicator,
}
pub async fn init_api_server(stop_token: StopToken, ready_indicator: ReadyIndicator) -> Result<()> {
let mut app = tide::with_state(State { ready_indicator });
app.at("/healthz").get(health_check);
app.at("/status").get(status);
app.at("/ready").get(readiness);
task::spawn(async move {
let listen = app.listen("0.0.0.0:8081").timeout_at(stop_token);
match listen.await {
Ok(result) => {
match result {
Ok(_) => info!("Api Server has cleanly shutdown"),
Err(e) => warn!("Api Server shutting down on error: {}", e),
};
}
Err(_) => info!("API Server shutdown. Received stop token."),
}
});
Ok(())
}
#[derive(Default)]
struct MetricsMiddleware {}
#[tide::utils::async_trait]
impl<State: Clone + Send + Sync + 'static> Middleware<State> for MetricsMiddleware {
async fn handle(&self, req: Request<State>, next: Next<'_, State>) -> tide::Result {
let res = next.run(req).await;
Ok(res)
}
}
async fn status(_req: tide::Request<State>) -> tide::Result {
Ok(Response::new(200))
}
async fn health_check(_req: tide::Request<State>) -> tide::Result {
Ok(Response::new(200))
}
async fn readiness(req: tide::Request<State>) -> tide::Result {
let ready = req.state().ready_indicator.inner().await;
if ready {
Ok(Response::new(200))
} else {
Ok(Response::new(500))
}
}