Release v0.6.0
Rust CI / Test & Quality Checks (push) Canceled after 0s
Rust CI / Build Docker Image (push) Canceled after 0s

This commit is contained in:
thakares committed 2026-08-09 17:17:57 +05:30
1 parent 7069ca9db7
commit f49698bb5c
75 files changed
+11199 -7508

No files matched your search

+49 -9
View File
@@ -1,33 +1,73 @@
use crate::db::Db;
use std::time::Duration;
use tracing::info;
use tracing::{error, info, warn};
/// Background job that marks expired URLs.
///
/// Runs every 60 seconds. Any URL with `expires_at < NOW()` and `expired = 0`
/// gets flipped to `expired = 1`.
pub async fn run_expiry_checker(db: Db) {
///
/// Correctness note: the redirect handler treats wall-clock `expires_at` as
/// authoritative and returns 410 without depending on this sweeper. The sweeper
/// is maintenance (persist `expired=1`) and must remain idempotent.
pub async fn run_expiry_checker(db: Db, mut shutdown_rx: tokio::sync::watch::Receiver<bool>) {
loop {
tokio::time::sleep(Duration::from_secs(60)).await;
tokio::select! {
_ = tokio::time::sleep(Duration::from_secs(60)) => {}
_ = shutdown_rx.changed() => {
info!("Expiry checker shutting down...");
break;
}
}
let user_ids: Vec<i64> = {
let conn = db.users.lock().unwrap();
let conn = match db.users.lock() {
Ok(c) => c,
Err(e) => {
error!(error = %e, "expiry job: users_db mutex poisoned");
continue;
}
};
let mut stmt = match conn.prepare("SELECT id FROM users;") {
Ok(s) => s,
Err(_) => continue,
Err(e) => {
error!(error = %e, "expiry job: failed to list users");
continue;
}
};
let rows = match stmt.query_map([], |row| row.get(0)) {
Ok(r) => r,
Err(_) => continue,
Err(e) => {
error!(error = %e, "expiry job: failed to map user ids");
continue;
}
};
rows.filter_map(|r| r.ok()).collect()
};
let mut total_expired = 0;
for user_id in user_ids {
if let Ok(conn) = super::open_user_content_conn(&db, user_id) {
let count = crate::db::content::expire_urls(&conn).unwrap_or(0);
total_expired += count;
match super::open_user_content_conn(&db, user_id) {
Ok(conn) => match crate::db::content::expire_urls(&conn) {
Ok(count) => total_expired += count,
Err(e) => {
warn!(
owner_user_id = user_id,
error = %e,
"expiry job: expire_urls failed"
);
}
},
Err(e) => {
// Missing content.db for a user is common; only log open errors that are unexpected.
if !matches!(e, rusqlite::Error::SqliteFailure(_, _)) {
warn!(
owner_user_id = user_id,
error = %e,
"expiry job: could not open content.db"
);
}
}
}
}