Documentation / Limites connues / Limites connues
Limites connues
Ce que Runique 4.0 ne fait pas encore, ou fait avec une restriction. Chaque ligne renvoie à la page qui explique la limite et ce qu'il faut faire en attendant. Les constats de sécurité ouverts sont tenus à part, dans faille.md à la racine du dépôt.
Base de données et migrations
| Limite | Détail |
|---|---|
Un moteur par compilation (sqlite, postgres, mysql)SQLite : un seul écrivain à la fois, SQLITE_BUSY sous forte chargeChanger de moteur demande une base neuve : les données ne sont pas transférées | Base de données |
Le changement de type d'une colonne n'est pas migré (--force écrit une migration vide, à compléter à la main)Des snapshots copiés sans leurs migrations font croire que les tables existent Identifiants SQL limités à 64 caractères sous MySQL / MariaDB migration up : une migration n'est atomique que sous Postgres (SQLite, MySQL / MariaDB : une migration qui échoue peut rester à moitié appliquée)Un arrêt brutal pendant makemigrations peut laisser des fichiers à moitié écrits (git pour restaurer) | Migrations, Makemigrations |
search! : in (vec) avec un vec vide, pas de filtre conditionnel inline | Requêtes |
Formulaires et messages
| Limite | Détail |
|---|---|
| Un échec d'écriture en session perd le message flash sans erreur | Macros flash |
| Un fichier publié puis une écriture en base qui échoue brutalement (coupure) peuvent laisser un fichier orphelin | Champs |
Sécurité, sessions, authentification
| Limite | Détail |
|---|---|
RateLimiter et LoginGuard n'ont pas de plafond mémoireRateLimiter et LoginGuard comptent par processus : avec plusieurs instances, le quota est multiplié | Rate limiting |
LoginGuard bloque par nom d'utilisateur : quelqu'un peut bloquer un compte dont il connaît le nom | LoginGuard |
| Le store de sessions mémoire appartient à un processus | Store de sessions |
Un store personnalisé (with_session_store) ne peut pas être parcouru par utilisateur : un reset de mot de passe ne ferme pas ses sessions | Session |
Mode Delegated : aucun fournisseur externe (OAuth, LDAP, SAML) n'est implémenté | Mots de passe |
| ACME : un seul site par machine (port 80 exclusif) | Réseau |
Admin
| Limite | Détail |
|---|---|
.links, .search_help, .empty_value acceptés mais sans effet sur l'affichage | Builder ModelAdmin |
Pas de feuille de thème globale (contournement par un bloc).with_htmx est global, pas de fragment de liste par modèleUn template de page ou une feuille de style absents ne sont signalés qu'à l'affichage | Surcharge |
| Pas d'interface de gestion des sessions | — |
| Many-to-many : déclaré dans le DSL par une table pivot, sans gestion dans l'admin | Évolutions |
Développement local
| Limite | Détail |
|---|---|
Les cookies ignorent le port : deux projets sur 127.0.0.1 partagent (et s'écrasent) le cookie de session | Dépannage |
Solutions en attendant
| Limite | Solution |
|---|---|
RateLimiter et LoginGuard sans plafond mémoire, compteurs par processus | Limiter aussi au reverse proxy (exemple ci-dessous) |
LoginGuard bloque par nom d'utilisateur | L'associer à une limite par IP, au reverse proxy ou avec RateLimiter |
| Store de sessions mémoire propre à un processus | Une seule instance, ou un reverse proxy qui renvoie chaque visiteur vers la même (ip_hash avec nginx) |
| ACME : un seul site par machine | Confier le TLS à un reverse proxy dès qu'il y a plusieurs sites |
| SQLite : un seul écrivain à la fois | PostgreSQL pour une charge en écriture soutenue |
| Migration atomique seulement sous PostgreSQL | Sauvegarder la base avant migration up sur SQLite et MySQL / MariaDB |
| Changement de type de colonne non migré | Compléter à la main la migration écrite par --force |
Cookies communs à deux projets sur 127.0.0.1 | Ouvrir l'un sur 127.0.0.1, l'autre sur localhost |
Limite par IP avec nginx, à adapter. La mémoire est plafonnée par la zone, et une requête refusée reçoit un code 503 par défaut :
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location /login {
limit_req zone=login burst=5 nodelay;
proxy_pass http://127.0.0.1:3000;
}