backend/db/
cronjobs.rs

1//! Scheduled tasks for the database.
2
3use chrono::{Days, Utc};
4use diesel::{debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, QueryDsl};
5use diesel_async::RunQueryDsl;
6use log::debug;
7use std::sync::Arc;
8
9use super::connection::Pool;
10
11use crate::schema::{layers, maps};
12
13/// How often the deleted maps are cleaned up in seconds.
14const CLEANUP_INTERVAL: u64 = 60 * 60 * 24;
15
16/// Permanently remove deleted maps older than 60 days from the database.
17/// Runs every [`CLEANUP_INTERVAL`] seconds.
18pub async fn cleanup_maps(pool: Arc<Pool>) -> ! {
19    loop {
20        tokio::time::sleep(std::time::Duration::from_secs(CLEANUP_INTERVAL)).await;
21        log::info!("Running maps cleanup...");
22
23        let Some(sixty_days_ago) = Utc::now().date_naive().checked_sub_days(Days::new(60)) else {
24            log::error!("Failed to calculate date 60 days ago");
25            continue;
26        };
27        let query = diesel::delete(
28            maps::table.filter(
29                maps::deletion_date
30                    .is_not_null()
31                    .and(maps::deletion_date.lt(sixty_days_ago)),
32            ),
33        );
34        debug!("{}", debug_query::<Pg, _>(&query));
35
36        match pool.get().await {
37            Ok(mut conn) => match query.execute(&mut conn).await {
38                Ok(delete_rows) => log::info!("Removed {delete_rows} maps"),
39                Err(e) => log::error!("Failed to execute query: {e}"),
40            },
41            Err(e) => {
42                log::error!("Failed to get connection from pool: {e}");
43            }
44        }
45    }
46}
47/// Permanently remove deleted layers older than 60 days from the database.
48/// Runs every [`CLEANUP_INTERVAL`] seconds.
49pub async fn cleanup_layers(pool: Arc<Pool>) -> ! {
50    loop {
51        tokio::time::sleep(std::time::Duration::from_secs(CLEANUP_INTERVAL)).await;
52
53        log::info!("Running layers cleanup...");
54
55        let sixty_days_ago = Utc::now().naive_utc() - chrono::Duration::days(60);
56        let query = diesel::delete(
57            layers::table.filter(
58                layers::marked_deleted
59                    .is_not_null()
60                    .and(layers::marked_deleted.lt(sixty_days_ago)),
61            ),
62        );
63        debug!("{}", debug_query::<Pg, _>(&query));
64
65        match pool.get().await {
66            Ok(mut conn) => match query.execute(&mut conn).await {
67                Ok(delete_rows) => log::info!("Removed {delete_rows} layers"),
68                Err(e) => log::error!("Failed to execute query: {e}"),
69            },
70            Err(e) => {
71                log::error!("Failed to get connection from pool: {e}");
72            }
73        }
74    }
75}