fc-server: session cleanup; conditional Secure cookie; kill_on_drop on NAR processes

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ie7b9002bbdc0ad91bb041f89979881956a6a6964
This commit is contained in:
raf 2026-02-15 23:30:04 +03:00
commit 9bbc1754d9
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
4 changed files with 70 additions and 17 deletions

View file

@ -7,6 +7,14 @@ use fc_common::{
};
use sqlx::PgPool;
/// Maximum session lifetime before automatic eviction (24 hours).
const SESSION_MAX_AGE: std::time::Duration =
std::time::Duration::from_secs(24 * 60 * 60);
/// How often the background cleanup task runs (every 5 minutes).
const SESSION_CLEANUP_INTERVAL: std::time::Duration =
std::time::Duration::from_secs(5 * 60);
/// Session data supporting both API key and user authentication
#[derive(Clone)]
pub struct SessionData {
@ -69,3 +77,27 @@ pub struct AppState {
pub sessions: Arc<DashMap<String, SessionData>>,
pub http_client: reqwest::Client,
}
impl AppState {
/// Spawn a background task that periodically evicts expired sessions.
/// This prevents unbounded memory growth from the in-memory session store.
pub fn spawn_session_cleanup(&self) {
let sessions = self.sessions.clone();
tokio::spawn(async move {
loop {
tokio::time::sleep(SESSION_CLEANUP_INTERVAL).await;
let before = sessions.len();
sessions
.retain(|_, session| session.created_at.elapsed() < SESSION_MAX_AGE);
let evicted = before - sessions.len();
if evicted > 0 {
tracing::debug!(
evicted = evicted,
remaining = sessions.len(),
"Evicted expired sessions"
);
}
}
});
}
}