Spawn an axum server

Concurrently spawn an axum server, which is not doing much yet, in
order to prepare for the creation, etc. of reminders.
This commit is contained in:
finga 2023-01-30 17:01:25 +01:00
parent 0434505b2d
commit 6b6f5aa48a
5 changed files with 519 additions and 84 deletions

View file

@ -1,12 +1,15 @@
use anyhow::Result;
use axum::{http::StatusCode, response::IntoResponse, Router};
use clap::Parser;
use diesel::{
prelude::*,
r2d2::{ConnectionManager, Pool, PooledConnection},
};
use lettre::{Message, SmtpTransport, Transport};
use std::{env, thread::park_timeout};
use std::{env, net::SocketAddr};
use time::{Duration, OffsetDateTime};
use tower::ServiceBuilder;
use tower_http::trace::TraceLayer;
use tracing::{debug, info, trace};
mod args;
@ -24,39 +27,51 @@ fn remind(
) -> Result<()> {
info!("checking for reminders");
for reminder in schema::reminders::dsl::reminders
let result = schema::reminders::dsl::reminders
.filter(schema::reminders::executed.is_null())
.order(schema::reminders::planned.asc())
.load::<Reminder>(db)?
{
trace!(?reminder, "checking reminder");
if reminder.planned <= OffsetDateTime::now_utc() {
let email = Message::builder()
.from("whakarite@localhost".parse()?)
.to(reminder.receiver.parse()?)
.subject(&reminder.title)
.body(reminder.message.to_string())?;
.load::<Reminder>(db)?;
mailer.send(&email)?;
if result.is_empty() {
info!("no reminders present, parking indefinitely");
std::thread::park();
} else {
for reminder in result {
trace!(?reminder, "checking reminder");
if reminder.planned <= OffsetDateTime::now_utc() {
let email = Message::builder()
.from("whakarite@localhost".parse()?)
.to(reminder.receiver.parse()?)
.subject(&reminder.title)
.body(reminder.message.to_string())?;
diesel::update(&reminder)
.set(schema::reminders::executed.eq(Some(OffsetDateTime::now_utc())))
.execute(db)?;
mailer.send(&email)?;
debug!("email sent to {}", reminder.receiver);
} else {
let duration = reminder.planned - OffsetDateTime::now_utc();
info!(?duration, "parking reminder");
diesel::update(&reminder)
.set(schema::reminders::executed.eq(Some(OffsetDateTime::now_utc())))
.execute(db)?;
park_timeout(<std::time::Duration>::try_from(duration)?);
debug!("email sent to {}", reminder.receiver);
} else {
let duration = reminder.planned - OffsetDateTime::now_utc();
info!(?duration, "parking reminder");
std::thread::park_timeout(<std::time::Duration>::try_from(duration)?);
return Ok(());
}
}
// Check for another remind job if none dont loop forever
}
Ok(())
}
fn main() -> Result<()> {
#[allow(clippy::unused_async)]
async fn not_found() -> impl IntoResponse {
(StatusCode::NOT_FOUND, "Page not found")
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
if env::var("RUST_LOG").is_err() {
@ -93,9 +108,25 @@ fn main() -> Result<()> {
.values(&test_reminder)
.execute(&mut db_pool.get()?)?;
let mailer = SmtpTransport::unencrypted_localhost();
std::thread::spawn(move || {
let mailer = SmtpTransport::unencrypted_localhost();
loop {
remind(&mut db_pool.get()?, &mailer)?;
}
loop {
remind(&mut db_pool.get().unwrap(), &mailer).unwrap();
}
});
let app = Router::new()
.layer(ServiceBuilder::new().layer(TraceLayer::new_for_http()))
.fallback(not_found);
let addr = SocketAddr::from((config.server.address, config.server.port));
info!("{} listening on {}", env!("CARGO_PKG_NAME"), addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await?;
Ok(())
}