Skip to main content

mail_laser/
lib.rs

1pub mod config;
2pub mod health;
3pub mod smtp;
4pub mod webhook;
5
6use acton_reactive::prelude::*;
7use anyhow::Result;
8use log::{error, info};
9
10pub async fn run() -> Result<()> {
11    info!(
12        "Starting {} v{}",
13        env!("CARGO_PKG_NAME"),
14        env!("CARGO_PKG_VERSION")
15    );
16
17    let config = match config::Config::from_env() {
18        Ok(config) => config,
19        Err(e) => {
20            error!("Failed to load configuration: {}", e);
21            return Err(e);
22        }
23    };
24
25    let mut runtime = ActonApp::launch_async().await;
26
27    // Create actors in dependency order
28    let webhook_handle = webhook::WebhookState::create(&mut runtime, &config).await?;
29    let _smtp_handle =
30        smtp::SmtpListenerState::create(&mut runtime, &config, webhook_handle).await?;
31    let _health_handle = health::HealthState::create(&mut runtime, &config).await?;
32
33    // Wait for shutdown signal (SIGTERM/SIGINT)
34    tokio::signal::ctrl_c().await?;
35    info!("Shutdown signal received, draining in-flight work...");
36
37    // Graceful shutdown: cancels accept loops (before_stop), finishes in-flight webhooks
38    runtime.shutdown_all().await?;
39    info!("Shutdown complete");
40
41    Ok(())
42}