use axum::Json;
use axum::extract::{Path, State};
use axum::http::StatusCode;
use lightshuttle_runtime::{LifecycleHandle, ResourceView};
use crate::error::ApiError;
use crate::state::ControlState;
pub(crate) async fn list_resources<H>(
State(state): State<ControlState<H>>,
) -> Result<Json<Vec<ResourceView>>, ApiError>
where
H: LifecycleHandle + Clone + Send + Sync + 'static,
{
let views = state.handle.list().await?;
Ok(Json(views))
}
pub(crate) async fn get_resource<H>(
State(state): State<ControlState<H>>,
Path(name): Path<String>,
) -> Result<Json<ResourceView>, ApiError>
where
H: LifecycleHandle + Clone + Send + Sync + 'static,
{
let view = state.handle.get(&name).await?;
Ok(Json(view))
}
pub(crate) async fn restart_resource<H>(
State(state): State<ControlState<H>>,
Path(name): Path<String>,
) -> Result<StatusCode, ApiError>
where
H: LifecycleHandle + Clone + Send + Sync + 'static,
{
let _ = state.handle.get(&name).await?;
crate::metrics::record_restart();
let handle = state.handle.clone();
let resource = name.clone();
tokio::spawn(async move {
if let Err(err) = handle.restart(&resource).await {
tracing::error!(error = %err, resource = %resource, "restart failed");
}
});
Ok(StatusCode::ACCEPTED)
}