this repo has no description
1use bspds::notifications::{EmailSender, NotificationService}; 2use bspds::state::AppState; 3use std::net::SocketAddr; 4use tokio::sync::watch; 5use tracing::{info, warn}; 6 7#[tokio::main] 8async fn main() { 9 dotenvy::dotenv().ok(); 10 tracing_subscriber::fmt::init(); 11 12 let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set"); 13 14 let pool = sqlx::postgres::PgPoolOptions::new() 15 .max_connections(5) 16 .connect(&database_url) 17 .await 18 .expect("Failed to connect to Postgres"); 19 20 sqlx::migrate!("./migrations") 21 .run(&pool) 22 .await 23 .expect("Failed to run migrations"); 24 25 let state = AppState::new(pool.clone()).await; 26 27 bspds::sync::listener::start_sequencer_listener(state.clone()).await; 28 let relays = std::env::var("RELAYS") 29 .unwrap_or_default() 30 .split(',') 31 .filter(|s| !s.is_empty()) 32 .map(|s| s.to_string()) 33 .collect(); 34 bspds::sync::relay_client::start_relay_clients(state.clone(), relays, None).await; 35 36 let (shutdown_tx, shutdown_rx) = watch::channel(false); 37 38 let mut notification_service = NotificationService::new(pool); 39 40 if let Some(email_sender) = EmailSender::from_env() { 41 info!("Email notifications enabled"); 42 notification_service = notification_service.register_sender(email_sender); 43 } else { 44 warn!("Email notifications disabled (MAIL_FROM_ADDRESS not set)"); 45 } 46 47 let notification_handle = tokio::spawn(notification_service.run(shutdown_rx)); 48 49 let app = bspds::app(state); 50 51 let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); 52 info!("listening on {}", addr); 53 let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); 54 55 let server_result = axum::serve(listener, app) 56 .with_graceful_shutdown(shutdown_signal(shutdown_tx)) 57 .await; 58 59 notification_handle.await.ok(); 60 61 if let Err(e) = server_result { 62 tracing::error!("Server error: {}", e); 63 } 64} 65 66async fn shutdown_signal(shutdown_tx: watch::Sender<bool>) { 67 let ctrl_c = async { 68 tokio::signal::ctrl_c() 69 .await 70 .expect("Failed to install Ctrl+C handler"); 71 }; 72 73 #[cfg(unix)] 74 let terminate = async { 75 tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) 76 .expect("Failed to install signal handler") 77 .recv() 78 .await; 79 }; 80 81 #[cfg(not(unix))] 82 let terminate = std::future::pending::<()>(); 83 84 tokio::select! { 85 _ = ctrl_c => {}, 86 _ = terminate => {}, 87 } 88 89 info!("Shutdown signal received, stopping services..."); 90 shutdown_tx.send(true).ok(); 91}