Skip to content
Clone
f0a1552
74 lines 2.3 KB Rust
use std::net::SocketAddr;
use std::time::Duration;
use anyhow::Context;
use config::scoped::{MailsConfig, ScopedConfig};
use email::runtime::{WorkerOptions, run_until_shutdown};
use tokio::net::TcpListener;
use tracing::info;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
init_tracing();
let cfg = MailsConfig::load().context("loading configuration")?;
let redis_url = cfg.redis.url().to_string();
let redis_host = match redis_url.rsplit_once('@') {
Some((_, host)) => host.to_string(),
None => redis_url.splitn(2, "://").nth(1).unwrap_or("?").to_string(),
};
info!(
smtp_enabled = cfg.email.enabled(),
queue_enabled = cfg.email_queue.enabled(),
redis = %redis_host,
shutdown_timeout_secs = 5,
"starting mails worker"
);
let opts = WorkerOptions {
template_dir: None,
shutdown_timeout: Some(Duration::from_secs(5)),
};
let (health_tx, health_rx) = tokio::sync::oneshot::channel::<()>();
let mut health_handle = None;
if cfg.health.enabled() {
let redis = export::AppRedis::connect(cfg.redis.clone())
.await
.context("connecting to redis")?;
let addr: SocketAddr = format!("{}:{}", cfg.health.bind_addr(), cfg.health.mails_port())
.parse()
.context("parsing health bind address")?;
let listener = TcpListener::bind(addr)
.await
.with_context(|| format!("binding health {addr}"))?;
info!(%addr, "mails health listening");
let router = export::health::router_with(None, redis);
health_handle = Some(tokio::spawn(async move {
let _ = axum::serve(listener, router)
.with_graceful_shutdown(async { let _ = health_rx.await; })
.await;
}));
}
let result =
run_until_shutdown(cfg.email.clone(), cfg.email_queue.clone(), redis_url, opts).await;
drop(health_tx);
if let Some(handle) = health_handle {
let _ = handle.await;
}
result.map_err(|e| anyhow::anyhow!(e.to_string()))?;
info!("mails worker exited cleanly");
Ok(())
}
fn init_tracing() {
use tracing_subscriber::EnvFilter;
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::fmt().with_env_filter(filter).init();
}