2021-05-09 14:17:24 -06:00
|
|
|
#![forbid(unsafe_code)]
|
|
|
|
|
2023-10-21 05:30:56 -06:00
|
|
|
use std::{future::Future, net::TcpListener};
|
2021-04-20 10:07:11 -06:00
|
|
|
|
2023-06-12 02:04:35 -06:00
|
|
|
use atuin_server_database::Database;
|
2022-04-12 16:06:19 -06:00
|
|
|
use axum::Server;
|
|
|
|
use eyre::{Context, Result};
|
2021-04-20 10:07:11 -06:00
|
|
|
|
2023-06-12 02:04:35 -06:00
|
|
|
mod handlers;
|
|
|
|
mod router;
|
|
|
|
mod settings;
|
|
|
|
mod utils;
|
2021-04-20 10:07:11 -06:00
|
|
|
|
2023-10-12 15:13:50 -06:00
|
|
|
pub use settings::example_config;
|
2023-06-12 02:04:35 -06:00
|
|
|
pub use settings::Settings;
|
2023-05-29 22:51:16 -06:00
|
|
|
use tokio::signal;
|
|
|
|
|
2023-06-19 01:14:03 -06:00
|
|
|
#[cfg(target_family = "unix")]
|
2023-05-29 22:51:16 -06:00
|
|
|
async fn shutdown_signal() {
|
2023-07-27 02:34:13 -06:00
|
|
|
let mut term = signal::unix::signal(signal::unix::SignalKind::terminate())
|
|
|
|
.expect("failed to register signal handler");
|
|
|
|
let mut interrupt = signal::unix::signal(signal::unix::SignalKind::interrupt())
|
|
|
|
.expect("failed to register signal handler");
|
|
|
|
|
|
|
|
tokio::select! {
|
|
|
|
_ = term.recv() => {},
|
|
|
|
_ = interrupt.recv() => {},
|
|
|
|
};
|
2023-05-29 22:51:16 -06:00
|
|
|
eprintln!("Shutting down gracefully...");
|
|
|
|
}
|
|
|
|
|
2023-06-19 01:14:03 -06:00
|
|
|
#[cfg(target_family = "windows")]
|
|
|
|
async fn shutdown_signal() {
|
|
|
|
signal::windows::ctrl_c()
|
|
|
|
.expect("failed to register signal handler")
|
|
|
|
.recv()
|
|
|
|
.await;
|
|
|
|
eprintln!("Shutting down gracefully...");
|
|
|
|
}
|
|
|
|
|
2023-06-12 02:04:35 -06:00
|
|
|
pub async fn launch<Db: Database>(
|
|
|
|
settings: Settings<Db::Settings>,
|
2023-10-21 05:30:56 -06:00
|
|
|
host: &str,
|
2023-06-12 02:04:35 -06:00
|
|
|
port: u16,
|
|
|
|
) -> Result<()> {
|
2023-07-27 02:34:13 -06:00
|
|
|
launch_with_listener::<Db>(
|
|
|
|
settings,
|
2023-10-21 05:30:56 -06:00
|
|
|
TcpListener::bind((host, port)).context("could not connect to socket")?,
|
2023-07-27 02:34:13 -06:00
|
|
|
shutdown_signal(),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
}
|
2021-04-20 10:07:11 -06:00
|
|
|
|
2023-07-27 02:34:13 -06:00
|
|
|
pub async fn launch_with_listener<Db: Database>(
|
|
|
|
settings: Settings<Db::Settings>,
|
|
|
|
listener: TcpListener,
|
|
|
|
shutdown: impl Future<Output = ()>,
|
|
|
|
) -> Result<()> {
|
2023-06-12 02:04:35 -06:00
|
|
|
let db = Db::new(&settings.db_settings)
|
2022-04-12 16:06:19 -06:00
|
|
|
.await
|
2023-06-12 02:04:35 -06:00
|
|
|
.wrap_err_with(|| format!("failed to connect to db: {:?}", settings.db_settings))?;
|
2021-04-20 10:07:11 -06:00
|
|
|
|
2023-06-12 02:04:35 -06:00
|
|
|
let r = router::router(db, settings);
|
2022-04-12 16:06:19 -06:00
|
|
|
|
2023-07-27 02:34:13 -06:00
|
|
|
Server::from_tcp(listener)
|
|
|
|
.context("could not launch server")?
|
2022-04-12 16:06:19 -06:00
|
|
|
.serve(r.into_make_service())
|
2023-07-27 02:34:13 -06:00
|
|
|
.with_graceful_shutdown(shutdown)
|
2022-04-12 16:06:19 -06:00
|
|
|
.await?;
|
2021-04-20 10:07:11 -06:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|