46 lines
1.7 KiB
Rust
46 lines
1.7 KiB
Rust
|
use async_std::{fs, path::PathBuf, sync::Receiver, task};
|
||
|
use chrono::{prelude::*, Duration};
|
||
|
use futures::future::FutureExt;
|
||
|
use sqlx::postgres::PgPool;
|
||
|
|
||
|
pub(crate) async fn delete_old_files(receiver: Receiver<()>, db: PgPool) {
|
||
|
loop {
|
||
|
wait_for_file_expiry(&receiver, &db).await;
|
||
|
let now = Local::now().naive_local();
|
||
|
let expired_files =
|
||
|
sqlx::query!("SELECT file_id FROM files WHERE files.valid_till < $1", now)
|
||
|
.fetch_all(&db)
|
||
|
.await
|
||
|
.unwrap();
|
||
|
for expired_file in expired_files {
|
||
|
let path = PathBuf::from(&format!("files/{}", expired_file.file_id));
|
||
|
if path.exists().await {
|
||
|
log::info!("delete file {}", expired_file.file_id);
|
||
|
fs::remove_file(&path).await.expect("could not delete file");
|
||
|
}
|
||
|
}
|
||
|
sqlx::query!("DELETE FROM files WHERE valid_till < $1", now)
|
||
|
.execute(&db)
|
||
|
.await
|
||
|
.expect("could not delete expired files from database");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async fn wait_for_file_expiry(receiver: &Receiver<()>, db: &PgPool) {
|
||
|
let row = sqlx::query!("SELECT MIN(valid_till) as min from files")
|
||
|
.fetch_one(db)
|
||
|
.await
|
||
|
.expect("could not fetch expiring file from database");
|
||
|
let next_timeout = match row.min {
|
||
|
Some(min) => min.signed_duration_since(Local::now().naive_local()),
|
||
|
None => Duration::days(1),
|
||
|
};
|
||
|
let positive_timeout = next_timeout
|
||
|
.to_std()
|
||
|
.unwrap_or_else(|_| std::time::Duration::from_secs(0));
|
||
|
futures::select! {
|
||
|
_ = task::sleep(positive_timeout).fuse() => {}
|
||
|
_ = receiver.recv().fuse() => {}
|
||
|
}
|
||
|
}
|