Sessions partagées entre workers¶
Objectif : comprendre pourquoi un déploiement multi-worker exige un store partagé, et comment DbSessionStore le fournit.
Ce que vous allez apprendre : en production, Gunicorn lance plusieurs processus (workers) pour servir les requêtes en parallèle.
Chaque worker a sa propre mémoire : un MemorySessionStore n'est donc pas partagé entre eux.
DbSessionStore range les sessions dans une base commune, que tous les workers lisent et écrivent.
Premier palier du niveau intermédiaire de la progression Sessions BDD.
Module opt-in
Si forge-mvc-sessions-db n'est pas installé, l'import échoue.
Le cœur de Forge, lui, ne dépend jamais de ce paquet.
Ce que ce starter montre¶
- pourquoi
MemorySessionStoreéchoue en multi-worker ; - comment
DbSessionStorepartage l'état via la base ; - brancher le store partagé une fois pour toute l'application.
Fonctions Forge utilisées¶
| Fonction | Rôle dans ce starter | Référence |
|---|---|---|
DbSessionStore(ttl=...) |
Construit un store partagé entre tous les processus. | Opt-ins |
forge.configure(session_store=...) |
Déclare ce store partagé pour l'application. | Opt-ins |
get(sid) |
Relit une session écrite par un autre worker. | Opt-ins |
1. Le problème du store mémoire en multi-worker¶
Gunicorn --workers 4 : quatre processus Python indépendants.
Worker A : crée la session S, la garde dans SON dictionnaire mémoire.
Worker B : reçoit la requête suivante, ne connaît pas S, la session semble perdue.
Comprendre ce code¶
- Chaque worker Gunicorn est un processus distinct, avec sa propre mémoire.
MemorySessionStorestocke les sessions dans un dictionnaire local à un seul processus.- Le répartiteur de charge envoie les requêtes à n'importe quel worker : l'utilisateur paraît déconnecté au hasard.
2. Le store BDD comme état partagé¶
import core.forge as forge
from forge_mvc_sessions_db import DbSessionStore
forge.configure(session_store=DbSessionStore(ttl=3600))
Comprendre ce code¶
- Tous les workers construisent leur
DbSessionStore, mais tous parlent à la même base viacore.database.db. - Une session créée par le worker A est écrite dans
forge_sessions, donc lisible par le worker B. - L'état partagé vit dans la base, pas dans la mémoire d'un processus : la répartition de charge devient transparente.
3. Vérifier le partage¶
from forge_mvc_sessions_db import DbSessionStore
# Worker A
store = DbSessionStore(ttl=3600)
sid = store.create({"utilisateur": "alice"})
# Worker B (autre processus, même base)
autre_store = DbSessionStore(ttl=3600)
print(autre_store.get(sid)["utilisateur"]) # alice
Comprendre ce code¶
- Deux instances de
DbSessionStore, dans deux processus, lisent la même table. get(sid)renvoie la session quel que soit le worker qui l'a créée.- C'est exactement le comportement attendu derrière un Gunicorn multi-worker.
À retenir¶
- Chaque worker Gunicorn est un processus séparé, avec sa propre mémoire.
MemorySessionStoren'est pas partagé entre workers : les sessions semblent aléatoirement perdues.DbSessionStorerange l'état dans une base commune, donc partagé par tous les workers.
Après ce starter¶
Les sessions partagées s'accumulent en base, y compris celles qui ont expiré.
Voyons comment les nettoyer.