85 lines
2.5 KiB
Rust
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");
|
|
},
|
|
}
|
|
}
|