lavina/src/main.rs

113 lines
2.8 KiB
Rust
Raw Normal View History

2023-09-30 23:50:04 +00:00
mod http;
2023-01-19 17:18:41 +00:00
2023-01-19 14:25:52 +00:00
use std::future::Future;
2023-09-22 15:24:36 +00:00
use std::path::Path;
2023-01-19 14:25:52 +00:00
2023-09-22 15:24:36 +00:00
use clap::Parser;
2023-01-19 14:25:52 +00:00
use figment::providers::Format;
use figment::{providers::Toml, Figment};
use prometheus::Registry as MetricsRegistry;
2023-01-19 14:25:52 +00:00
use serde::Deserialize;
2023-09-30 23:12:11 +00:00
use lavina_core::player::PlayerRegistry;
use lavina_core::prelude::*;
2023-09-30 23:12:11 +00:00
use lavina_core::repo::Storage;
use lavina_core::room::RoomRegistry;
2023-01-19 14:25:52 +00:00
#[derive(Deserialize, Debug)]
struct ServerConfig {
2023-09-30 23:50:04 +00:00
telemetry: http::ServerConfig,
irc: projection_irc::ServerConfig,
xmpp: projection_xmpp::ServerConfig,
2023-09-30 23:12:11 +00:00
storage: lavina_core::repo::StorageConfig,
2023-01-19 14:25:52 +00:00
}
2023-09-22 15:24:36 +00:00
#[derive(Parser)]
struct CliArgs {
#[arg(long)]
2023-09-30 23:50:04 +00:00
config: Box<Path>,
2023-09-22 15:24:36 +00:00
}
2023-01-19 14:25:52 +00:00
fn load_config() -> Result<ServerConfig> {
2023-09-22 15:24:36 +00:00
let args = CliArgs::parse();
let raw_config = Figment::from(Toml::file(args.config));
2023-01-19 14:25:52 +00:00
let config: ServerConfig = raw_config.extract()?;
Ok(config)
}
#[tokio::main]
async fn main() -> Result<()> {
set_up_logging()?;
let sleep = ctrl_c()?;
let config = load_config()?;
2023-01-27 20:43:20 +00:00
tracing::info!("Booting up");
tracing::info!("Loaded config: {config:?}");
2023-02-10 17:09:29 +00:00
let ServerConfig {
telemetry: telemetry_config,
irc: irc_config,
xmpp: xmpp_config,
2023-07-07 13:09:24 +00:00
storage: storage_config,
2023-02-10 17:09:29 +00:00
} = config;
2023-02-12 22:23:52 +00:00
let mut metrics = MetricsRegistry::new();
2023-07-07 13:09:24 +00:00
let storage = Storage::open(storage_config).await?;
2023-08-17 13:41:28 +00:00
let rooms = RoomRegistry::new(&mut metrics, storage.clone())?;
let mut players = PlayerRegistry::empty(rooms.clone(), storage.clone(), &mut metrics)?;
2023-09-30 23:50:04 +00:00
let telemetry_terminator = http::launch(telemetry_config, metrics.clone(), rooms.clone(), storage.clone()).await?;
let irc = projection_irc::launch(
irc_config,
players.clone(),
rooms.clone(),
metrics.clone(),
storage.clone(),
)
.await?;
2024-03-20 18:59:15 +00:00
let xmpp = projection_xmpp::launch(
xmpp_config,
players.clone(),
rooms.clone(),
metrics.clone(),
storage.clone(),
)
.await?;
2023-01-19 14:25:52 +00:00
tracing::info!("Started");
sleep.await;
2023-01-19 14:25:52 +00:00
tracing::info!("Begin shutdown");
xmpp.terminate().await?;
2023-02-07 15:21:00 +00:00
irc.terminate().await?;
telemetry_terminator.terminate().await?;
2023-08-24 12:10:31 +00:00
players.shutdown_all().await?;
drop(players);
drop(rooms);
storage.close().await?;
2023-01-19 14:25:52 +00:00
tracing::info!("Shutdown complete");
Ok(())
}
2023-07-30 16:59:33 +00:00
#[cfg(windows)]
fn ctrl_c() -> Result<impl Future<Output = ()>> {
use tokio::signal::windows::*;
let chan = ctrl_c()?;
async fn recv(mut chan: CtrlC) {
let _ = chan.recv().await;
}
Ok(recv(chan))
}
#[cfg(unix)]
2023-01-19 14:25:52 +00:00
fn ctrl_c() -> Result<impl Future<Output = ()>> {
use tokio::signal::unix::*;
let chan = signal(SignalKind::interrupt())?;
async fn recv(mut chan: Signal) {
let _ = chan.recv().await;
}
Ok(recv(chan))
}
fn set_up_logging() -> Result<()> {
tracing_subscriber::fmt::init();
Ok(())
}