From 99009aae9ae1df46f13fc722ea152fcf793cb14a Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Sat, 8 Aug 2026 20:23:58 +0800 Subject: [PATCH] db: share one now_f64() instead of four private copies handlers, queue, send and link_cache each carried the same SystemTime helper; a single crate::db::now_f64() removes the drift risk. --- crates/xmedia-bot/src/db.rs | 9 +++++++++ crates/xmedia-bot/src/handlers.rs | 8 +------- crates/xmedia-bot/src/link_cache.rs | 8 +------- crates/xmedia-bot/src/queue.rs | 10 ++-------- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/crates/xmedia-bot/src/db.rs b/crates/xmedia-bot/src/db.rs index 89dcdcb..36844a1 100644 --- a/crates/xmedia-bot/src/db.rs +++ b/crates/xmedia-bot/src/db.rs @@ -19,6 +19,15 @@ pub fn open_db(path: &str) -> rusqlite::Result { Ok(conn) } +/// Unix timestamp in fractional seconds. Shared by the queue, chat store and +/// link cache (previously four private copies). +pub fn now_f64() -> f64 { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map(|d| d.as_secs_f64()) + .unwrap_or(0.0) +} + /// Runs `f` against a fresh connection on a blocking thread, returning the /// closure's result. Owns the `spawn_blocking` + `expect` ceremony shared by /// every table access; the caller maps errors to its own log line. diff --git a/crates/xmedia-bot/src/handlers.rs b/crates/xmedia-bot/src/handlers.rs index 3bdf887..f17d6c5 100644 --- a/crates/xmedia-bot/src/handlers.rs +++ b/crates/xmedia-bot/src/handlers.rs @@ -1,4 +1,5 @@ use crate::config::Config; +use crate::db::now_f64; use crate::link_cache::{CachedMediaKind, CachedPost, LinkCache}; use crate::queue::PersistentTaskQueue; use crate::send::{self, MediaItemPayload, Task}; @@ -111,13 +112,6 @@ where .await } -fn now_f64() -> f64 { - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .map(|d| d.as_secs_f64()) - .unwrap_or(0.0) -} - /// Extracts URL and text-link entities (text + caption), deduped in order. pub fn extract_urls(message: &Message) -> Vec { let mut urls = Vec::new(); diff --git a/crates/xmedia-bot/src/link_cache.rs b/crates/xmedia-bot/src/link_cache.rs index 62025e3..cf25850 100644 --- a/crates/xmedia-bot/src/link_cache.rs +++ b/crates/xmedia-bot/src/link_cache.rs @@ -8,6 +8,7 @@ //! [`Config::link_cache_ttl`]; a stale entry is dropped lazily on read and //! by the periodic prune in `main`. +use crate::db::now_f64; use rusqlite::{Connection, params}; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -163,13 +164,6 @@ impl LinkCache { } } -fn now_f64() -> f64 { - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .map(|d| d.as_secs_f64()) - .unwrap_or(0.0) -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/xmedia-bot/src/queue.rs b/crates/xmedia-bot/src/queue.rs index fa2fc0a..919acb9 100644 --- a/crates/xmedia-bot/src/queue.rs +++ b/crates/xmedia-bot/src/queue.rs @@ -5,13 +5,14 @@ //! flow. The Python dict-mutation hack (attempts inside the payload) is //! replaced by dedicated columns. +use crate::db::now_f64; use parking_lot::Mutex; use rusqlite::{Connection, TransactionBehavior, params}; use serde_json::Value; use std::pin::Pin; use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; +use std::time::Duration; use tokio::sync::Notify; use tokio::task::JoinHandle; @@ -62,13 +63,6 @@ struct QueueWorker { dead_letter: Arc, } -fn now_f64() -> f64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .map(|d| d.as_secs_f64()) - .unwrap_or(0.0) -} - /// Resets rows left `in_progress` with an expired lock TTL back to `pending` /// so they can be leased again (crash/panic recovery). fn recover_update(conn: &rusqlite::Connection) -> rusqlite::Result<()> {