diff --git a/.cargo/config b/.cargo/config index fb58920..28844e0 100644 --- a/.cargo/config +++ b/.cargo/config @@ -4,4 +4,5 @@ rustflags = [ "-Dclippy::pedantic", "-Dclippy::nursery", "-Dclippy::cargo", + "-Aclippy::multiple-crate-versions", ] diff --git a/Cargo.lock b/Cargo.lock index b8ad3d9..6053171 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,9 +348,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" @@ -466,12 +466,12 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -483,7 +483,7 @@ dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -592,7 +592,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -727,15 +727,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -890,7 +890,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -911,7 +911,7 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1075,9 +1075,9 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "tempfile" @@ -1190,7 +1190,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1472,6 +1472,30 @@ dependencies = [ "windows_x86_64_msvc", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.1" diff --git a/src/api.rs b/src/api.rs index a7dfd3c..a0eabda 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,4 +1,4 @@ -use crate::{schema, NewReminder}; +use crate::{schema, AppState, NewReminder}; use anyhow::Error; use axum::{ extract::State, @@ -6,10 +6,7 @@ use axum::{ response::{IntoResponse, Response, Result}, Json, }; -use diesel::{ - prelude::*, - r2d2::{ConnectionManager, Pool}, -}; +use diesel::prelude::*; use serde::Deserialize; use time::OffsetDateTime; use tracing::{error, trace}; @@ -33,7 +30,7 @@ where } #[derive(Debug, Deserialize)] -pub struct CreateReminder { +pub struct Reminder { #[serde(with = "time::serde::iso8601")] planned: OffsetDateTime, title: String, @@ -43,8 +40,8 @@ pub struct CreateReminder { #[allow(clippy::unused_async)] pub async fn create_reminder( - State(db_pool): State>>, - Json(data): Json, + State(state): State, + Json(data): Json, ) -> Result { let reminder = NewReminder { created: OffsetDateTime::now_utc(), @@ -58,7 +55,10 @@ pub async fn create_reminder( diesel::insert_into(schema::reminders::table) .values(&reminder) - .execute(&mut db_pool.get()?)?; + .execute(&mut state.db_pool.get()?)?; + + trace!("unpark reminder thread to reschedule next run"); + state.reminder.thread().unpark(); Ok((StatusCode::CREATED, "Reminder created".to_string())) } diff --git a/src/main.rs b/src/main.rs index e52aee9..771ad32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use diesel::{ r2d2::{ConnectionManager, Pool}, }; use lettre::{Message, SmtpTransport, Transport}; -use std::{env, net::SocketAddr, time::Duration}; +use std::{env, net::SocketAddr, sync::Arc, thread::JoinHandle, time::Duration}; use time::OffsetDateTime; use tower::ServiceBuilder; use tower_http::trace::TraceLayer; @@ -80,6 +80,12 @@ fn remind( Ok(()) } +#[derive(Clone)] +pub struct AppState { + db_pool: Pool>, + reminder: Arc>>, +} + #[tokio::main] async fn main() -> Result<()> { let args = Args::parse(); @@ -97,25 +103,23 @@ async fn main() -> Result<()> { ); let config = Config::load_config(args.config)?; - let mut db_pool = get_connection_pool(&config)?; - - std::thread::spawn(move || -> Result<(), Error> { + let reminder = std::thread::spawn(move || -> Result<(), Error> { let mailer = SmtpTransport::unencrypted_localhost(); loop { remind(&mut db_pool, &mailer)?; } }); - let db_pool = get_connection_pool(&config)?; - let app = Router::new() .route("/v1/reminder", post(api::create_reminder)) .layer(ServiceBuilder::new().layer(TraceLayer::new_for_http())) .fallback(api::not_found) - .with_state(db_pool); - + .with_state(AppState { + db_pool, + reminder: Arc::new(reminder), + }); let addr = SocketAddr::from((config.server.address, config.server.port)); info!("{} listening on {}", env!("CARGO_PKG_NAME"), addr);