shoutdotdev/src/main.rs

135 lines
3.9 KiB
Rust
Raw Normal View History

2025-03-14 13:04:57 -07:00
use app_state::App;
use axum::middleware::map_request;
2025-03-08 22:18:24 -08:00
use chrono::{TimeDelta, Utc};
use clap::{Parser, Subcommand};
2025-03-11 10:33:37 -07:00
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
2025-03-14 13:04:57 -07:00
use dotenvy::dotenv;
use middleware::lowercase_uri_path;
2025-03-08 22:18:24 -08:00
use tokio::time::sleep;
use tower::ServiceBuilder;
use tower_http::{
compression::CompressionLayer, normalize_path::NormalizePathLayer, trace::TraceLayer,
};
2025-02-26 13:10:50 -08:00
use tracing_subscriber::EnvFilter;
2025-03-14 13:04:57 -07:00
use crate::{app_state::AppState, router::new_router, settings::Settings, worker::run_worker};
pub mod api_keys;
pub mod app_error;
pub mod app_state;
pub mod auth;
pub mod channel_selections;
pub mod channels;
mod channels_router;
pub mod csrf;
pub mod email;
pub mod governors;
pub mod guards;
pub mod messages;
pub mod middleware;
mod nav_state;
pub mod projects;
mod projects_router;
pub mod router;
pub mod schema;
pub mod sessions;
pub mod settings;
pub mod team_memberships;
pub mod teams;
mod teams_router;
pub mod users;
mod v0_router;
pub mod worker;
2025-02-26 13:10:50 -08:00
2025-03-08 22:18:24 -08:00
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Run web server
Serve,
/// Run background worker
Worker {
/// Loop the every n seconds instead of exiting after execution
#[arg(long)]
auto_loop_seconds: Option<u32>,
},
// TODO: add a low-frequency worker task exclusively for self-healing
// mechanisms like Governor::reset_all()
2025-03-08 22:18:24 -08:00
}
2025-03-14 13:04:57 -07:00
/// Run CLI
2025-02-26 13:10:50 -08:00
#[tokio::main]
async fn main() {
2025-03-14 13:04:57 -07:00
// Attempt to pre-load .env in case it contains a RUST_LOG variable
dotenv().ok();
2025-02-26 13:10:50 -08:00
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
2025-03-11 10:29:22 -07:00
let settings = Settings::load().unwrap();
2025-03-14 13:04:57 -07:00
let state: AppState = App::from_settings(settings.clone()).await.unwrap().into();
2025-02-26 13:10:43 -08:00
2025-03-11 10:33:37 -07:00
if settings.run_database_migrations == Some(1) {
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations/");
// Run migrations on server startup
2025-03-14 13:04:57 -07:00
let conn = state.db_pool.get().await.unwrap();
2025-03-11 10:33:37 -07:00
conn.interact(|conn| conn.run_pending_migrations(MIGRATIONS).map(|_| ()))
.await
.unwrap()
.unwrap();
}
2025-03-14 13:04:57 -07:00
let cli = Cli::parse();
2025-03-08 22:18:24 -08:00
match &cli.command {
Commands::Serve => {
2025-03-14 13:04:57 -07:00
let router = new_router(state.clone()).layer(
ServiceBuilder::new()
.layer(map_request(lowercase_uri_path))
.layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new())
.layer(NormalizePathLayer::trim_trailing_slash()),
);
2025-02-26 13:10:50 -08:00
2025-03-14 13:04:57 -07:00
let listener = tokio::net::TcpListener::bind((settings.host.clone(), settings.port))
.await
.unwrap();
2025-03-08 22:18:24 -08:00
tracing::info!(
"App running at http://{}:{}{}",
settings.host,
settings.port,
settings.base_path
);
2025-03-14 13:04:57 -07:00
axum::serve(listener, router).await.unwrap();
2025-03-08 22:18:24 -08:00
}
Commands::Worker { auto_loop_seconds } => {
if let Some(loop_seconds) = auto_loop_seconds {
let loop_delta = TimeDelta::seconds(i64::from(*loop_seconds));
loop {
let t_next_loop = Utc::now() + loop_delta;
2025-03-14 13:04:57 -07:00
if let Err(err) = run_worker(state.clone()).await {
2025-03-08 22:18:24 -08:00
tracing::error!("{}", err)
}
let sleep_delta = t_next_loop - Utc::now();
match sleep_delta.to_std() {
Ok(duration) => {
sleep(duration).await;
}
Err(_) => { /* sleep_delta was < 0, so don't sleep */ }
}
}
} else {
2025-03-14 13:04:57 -07:00
run_worker(state).await.unwrap();
2025-03-08 22:18:24 -08:00
}
}
}
2025-02-26 13:10:50 -08:00
}