personal_token_cleanup.rs 50 lignes · 2063 octets
//! Personal access token cleanup task.
//!
//! Periodically hard-deletes PATs that are both expired AND revoked. See
//! [`PersonalTokenService::cleanup_expired`](crate::services::personal_token_service::PersonalTokenService::cleanup_expired)
//! for the exact predicate.

use crate::services::personal_token_service::{PersonalTokenService, TokenScope};
use sea_orm::DatabaseConnection;
use std::marker::PhantomData;
use std::sync::Arc;
use tokio::time::Duration;

/// Background processor that periodically drops expired+revoked PAT rows.
///
/// Generic over the app's scope vocabulary only so that
/// [`PersonalTokenService::<S>::cleanup_expired`] can be reached — the
/// predicate itself is scope-agnostic.
pub struct PersonalTokenCleanupProcessor<S: TokenScope> {
    db: Arc<DatabaseConnection>,
    _phantom: PhantomData<S>,
}

impl<S: TokenScope> PersonalTokenCleanupProcessor<S> {
    /// Create a new cleanup processor bound to the given database connection.
    pub fn new(db: Arc<DatabaseConnection>) -> Self {
        Self {
            db,
            _phantom: PhantomData,
        }
    }

    /// Spawn the cleanup loop. First tick fires immediately (to purge stale
    /// rows on process start), then every
    /// [`config::tasks::personal_token_cleanup_interval_secs`](crate::config::tasks::personal_token_cleanup_interval_secs).
    pub fn start(self) {
        tokio::spawn(async move {
            let secs = crate::config::tasks::personal_token_cleanup_interval_secs();
            let mut ticker = tokio::time::interval(Duration::from_secs(secs));
            ticker.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
            loop {
                ticker.tick().await;
                match PersonalTokenService::<S>::cleanup_expired(&self.db).await {
                    Ok(0) => {}
                    Ok(n) => tracing::info!("PAT cleanup: deleted {} expired+revoked token(s)", n),
                    Err(e) => tracing::error!("PAT cleanup failed: {}", e),
                }
            }
        });
    }
}