From bd7d936dbda8c0a8dcdc13e90697f565ddddcebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Tue, 25 Oct 2022 23:51:50 +0200 Subject: [PATCH] Shorten the time until the next tick if it's required to send a start notification --- src/main.rs | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 628bc5d..55512e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,14 +4,16 @@ mod db; mod error; mod schema; -use std::{env, fs::File, io::BufReader, sync::Arc, time::Duration}; +use std::time::Duration; +use std::{env, fs::File, io::BufReader, sync::Arc}; use anyhow::Result; use async_mutex::Mutex; use bot::fetch_and_announce_appointment; -use chrono::{DateTime, NaiveTime, TimeZone, Utc}; +use chrono::{DateTime, NaiveDateTime, NaiveTime, TimeZone, Utc}; use chrono_tz::Europe; use db::ChatInfo; +use diesel::result::Error::NotFound; use diesel::{Connection, RunQueryDsl, SqliteConnection}; use diesel::{ExpressionMethods, QueryDsl}; use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; @@ -23,7 +25,7 @@ use teloxide::prelude::RequesterExt; use teloxide::requests::Requester; use teloxide::types::ChatId; use teloxide::{adaptors::throttle::Limits, Bot}; -use tokio::time::interval; +use tokio::time::sleep; use crate::db::DbChat; @@ -77,11 +79,36 @@ async fn main() { { let db = db.clone(); let bot = bot.clone(); + let poll_duration = Duration::from_secs(config.poll_interval); tokio::task::spawn(async move { - let mut interval = interval(Duration::from_secs(config.poll_interval)); - interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); loop { - interval.tick().await; + let now = Utc::now(); + + let next_appointment = db.lock().await.transaction(|db| { + use schema::chat::dsl::*; + chat.select(next_appointment_start) + .filter(next_appointment_start.is_not_null()) + .filter(next_appointment_start.gt(now.timestamp())) + .order(next_appointment_start.asc()) + .first::>(db) + }); + + let next_appointment = match next_appointment { + Err(NotFound) => None, + Ok(appointment) => appointment, + Err(e) => Err(e).unwrap(), + }; + + let sleep_duration = next_appointment + .map(|timestamp| NaiveDateTime::from_timestamp(timestamp, 0)) + .map(|naive_date_time| DateTime::::from_utc(naive_date_time, Utc)) + .map(|date_time| date_time - now) + .map(|duration| duration.to_std().unwrap()) + .filter(|duration| *duration < poll_duration) + .unwrap_or(poll_duration); + + sleep(sleep_duration).await; + // TODO Log the error and continue instead check_task(&bot, config.reminder_time, &db).await.unwrap(); }