sparse-v2/sparse-server/src/webserver.rs
2025-02-01 15:59:56 -05:00

85 lines
2.5 KiB
Rust

use std::{net::SocketAddrV4, process::ExitCode};
use sqlx::sqlite::SqlitePool;
use axum::Router;
use leptos::prelude::*;
use leptos_axum::{generate_route_list, LeptosRoutes};
use tokio::signal;
use sparse_server::app::*;
pub async fn serve_web(management_address: SocketAddrV4, db: SqlitePool) -> anyhow::Result<ExitCode> {
let conf = get_configuration(None).unwrap();
let leptos_options = conf.leptos_options;
let routes = generate_route_list(App);
let beacon_listeners = sparse_handler::BeaconListenerMap::default();
let compression_layer = tower_http::compression::CompressionLayer::new()
.gzip(true)
.deflate(true)
.br(true)
.zstd(true);
sparse_handler::start_all_listeners(beacon_listeners.clone(), db.clone()).await?;
let app = Router::new()
.leptos_routes_with_context(
&leptos_options,
routes,
move || {
provide_context(beacon_listeners.clone());
provide_context::<SqlitePool>(db.clone());
},
{
let leptos_options = leptos_options.clone();
move || shell(leptos_options.clone())
}
)
.fallback(leptos_axum::file_and_error_handler::<leptos::config::LeptosOptions, _>(shell))
.with_state(leptos_options)
.layer(
tower::ServiceBuilder::new()
.layer(tower_http::trace::TraceLayer::new_for_http())
.layer(compression_layer)
);
// run our app with hyper
// `axum::Server` is a re-export of `hyper::Server`
let management_listener = tokio::net::TcpListener::bind(&management_address).await?;
tracing::info!("management interface listening on http://{}", &management_address);
axum::serve(management_listener, app.into_make_service())
.with_graceful_shutdown(shutdown_signal())
.await?;
Ok(ExitCode::SUCCESS)
}
async fn shutdown_signal() {
let ctrl_c = async {
signal::ctrl_c()
.await
.expect("failed to install Ctrl+C handler");
};
#[cfg(unix)]
let terminate = async {
signal::unix::signal(signal::unix::SignalKind::terminate())
.expect("failed to install signal handler")
.recv()
.await;
};
#[cfg(not(unix))]
let terminate = std::future::pending::<()>();
tokio::select! {
_ = ctrl_c => {
tracing::info!("Received Ctrl-C");
},
_ = terminate => {
tracing::info!("Received terminate command");
},
}
}