diff --git a/crates/cli/src/server.rs b/crates/cli/src/server.rs index aef413bb..fe6cb412 100644 --- a/crates/cli/src/server.rs +++ b/crates/cli/src/server.rs @@ -22,6 +22,7 @@ use clap::Clap; use hyper::{header, Server}; use mas_config::RootConfig; use mas_core::{ + storage::MIGRATOR, tasks::{self, TaskQueue}, templates::Templates, }; @@ -32,11 +33,16 @@ use tower_http::{ trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer}, LatencyUnit, }; +use tracing::info; use super::RootCommand; #[derive(Clap, Debug, Default)] -pub(super) struct ServerCommand; +pub(super) struct ServerCommand { + /// Automatically apply pending migrations + #[clap(long)] + migrate: bool, +} impl ServerCommand { pub async fn run(&self, root: &RootCommand) -> anyhow::Result<()> { @@ -48,6 +54,19 @@ impl ServerCommand { // Connect to the database let pool = config.database.connect().await?; + if self.migrate { + info!("Running pending migrations"); + MIGRATOR + .run(&pool) + .await + .context("could not run migrations")?; + } + + info!("Starting task scheduler"); + let queue = TaskQueue::default(); + queue.recuring(Duration::from_secs(15), tasks::cleanup_expired(&pool)); + queue.start(); + // Load and compile the templates // TODO: custom template path from the config let templates = Templates::load(None, true).context("could not load templates")?; @@ -55,10 +74,6 @@ impl ServerCommand { // Start the server let root = mas_core::handlers::root(&pool, &templates, &config); - let queue = TaskQueue::default(); - queue.recuring(Duration::from_secs(15), tasks::cleanup_expired(&pool)); - queue.start(); - let warp_service = warp::service(root); let service = ServiceBuilder::new() @@ -83,7 +98,7 @@ impl ServerCommand { ])) .service(warp_service); - tracing::info!("Listening on http://{}", listener.local_addr().unwrap()); + info!("Listening on http://{}", listener.local_addr().unwrap()); Server::from_tcp(listener)? .serve(Shared::new(service)) diff --git a/crates/core/src/tasks/database.rs b/crates/core/src/tasks/database.rs index a1ff265e..3189127b 100644 --- a/crates/core/src/tasks/database.rs +++ b/crates/core/src/tasks/database.rs @@ -20,6 +20,12 @@ use super::Task; #[derive(Clone)] struct CleanupExpired(Pool); +impl std::fmt::Debug for CleanupExpired { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CleanupExpired").finish_non_exhaustive() + } +} + #[async_trait::async_trait] impl Task for CleanupExpired { async fn run(&self) { diff --git a/crates/core/src/tasks/mod.rs b/crates/core/src/tasks/mod.rs index 0f82b799..84849746 100644 --- a/crates/core/src/tasks/mod.rs +++ b/crates/core/src/tasks/mod.rs @@ -20,13 +20,14 @@ use tokio::{ time::Interval, }; use tokio_stream::wrappers::IntervalStream; +use tracing::debug; mod database; pub use self::database::cleanup_expired; #[async_trait::async_trait] -pub trait Task: Send + Sync + 'static { +pub trait Task: std::fmt::Debug + Send + Sync + 'static { async fn run(&self); } @@ -93,7 +94,8 @@ impl TaskQueue { queue.schedule(task).await; } - pub fn recuring(&self, every: Duration, task: impl Task + Clone) { + pub fn recuring(&self, every: Duration, task: impl Task + Clone + std::fmt::Debug) { + debug!(?task, period = every.as_secs(), "Scheduling recuring task"); let queue = self.inner.clone(); tokio::task::spawn(async move { queue.recuring(tokio::time::interval(every), task).await;