Sessions

Store & watermarks

CleaningMemoryStore

Pourquoi

Le MemoryStore de tower-sessions n'implémente pas de nettoyage des sessions expirées. Sans purge, chaque requête d'un bot sans cookies crée une session qui ne sera jamais supprimée — la mémoire croît indéfiniment.

CleaningMemoryStore résout ce problème avec trois mécanismes :

MécanismeDéclencheurComportement
Timer périodiqueToutes les 60s (configurable)Supprime toutes les sessions expirées
Low watermark128 Mo (configurable)Purge asynchrone des sessions anonymes expirées
High watermark256 Mo (configurable)Purge synchrone d'urgence + refus (503) si insuffisant

Estimation de la taille

Chaque record est estimé à : 24 octets (UUID + expiry) + taille JSON des données.

Une alerte est loggée si un record dépasse 50 Ko (image ou fichier stocké en session par erreur).


Système de watermarks

Low watermark (128 Mo par défaut)

Lorsque la taille totale du store dépasse ce seuil, un cleanup non-bloquant est lancé en arrière-plan via tokio::spawn. Il supprime les sessions anonymes expirées sans interrompre la requête en cours.

High watermark (256 Mo par défaut)

Lorsque la taille dépasse ce seuil au moment de créer une session :

  1. Passe 1 — supprime les sessions anonymes expirées
  2. Passe 2 — si toujours dépassé, supprime toutes les sessions expirées (y compris authentifiées)
  3. Refus — si toujours dépassé, retourne 503 Service Unavailable

Les sessions protégées ne sont jamais sacrifiées en passe 1.



Persistance — fallback base de données

Par défaut, le store est purement en mémoire. Lorsque la feature orm est active, un fallback base de données est activé automatiquement pour les sessions authentifiées — aucune configuration supplémentaire n'est nécessaire.

  • Lecture : mémoire d'abord, DB en cas de miss (session survit à un redémarrage)
  • Écriture : synchrone en mémoire + asynchrone en DB pour les sessions avec user_id
  • Sessions anonymes : jamais persistées en DB

La table eihwaz_sessions doit exister — elle est créée par les migrations du framework.


Configuration

Tous les seuils décrits ci-dessus sont réglables depuis le builder, dans le bloc .middleware(). Aucune construction manuelle du store n'est nécessaire — le framework instancie CleaningMemoryStore et applique ces valeurs.

use runique::prelude::*;
use time::Duration;

let app = RuniqueApp::builder(config)
    // TTL d'inactivité avant expiration (sessions authentifiées)
    .with_session_duration(Duration::hours(2))
    .middleware(|m| {
        m
            // Low / high watermark — en octets
            .with_session_memory_limit(64 * 1024 * 1024, 128 * 1024 * 1024)
            // Intervalle du timer de purge périodique — en secondes
            .with_session_cleanup_interval(30)
            // Un seul appareil connecté à la fois par utilisateur
            .with_exclusive_login(true)
    })
    .build()
    .await?;
Mécanisme (section ci-dessus)Méthode builderDéfaut
Timer périodiquewith_session_cleanup_interval(secs)60 s
Low / High watermarkwith_session_memory_limit(low, high)128 Mo / 256 Mo
TTL session authentifiéewith_session_duration(Duration)
TTL session anonymewith_anonymous_session_duration(Duration)
Login exclusif (un appareil)with_exclusive_login(bool)false

Les watermarks s'expriment en octets : 64 * 1024 * 1024 = 64 Mo. La durée du timer est en secondes.