Voila une petite question liée à l'utilisation du cache sur Rails. Pour mettre en cache j'ai plusieurs solutions :

  • Le page caching ou je cache toute la page, inutilisable car j'ai plusieurs éléments de la page qui dépendent de l'état de connexion de l'utilisateur.
  • L'action caching , semble une solution idéale pour cacher seulement le résultat d'une action mais cela m'mpèche de passer des variables de la vue au layout (comme le title ou les métas)
  • Le fragment caching , permet de cacher un morceau de ma vue. Mais les controllers étant appelés les requêtes vont quand même se faire et ralentir le tout
  • Le serveur HTTP Varnish , pareil que le page caching, il empêche l'éxécution des scripts de reconnexion des utilisateurs et nécessite une configuration pointue

Donc ma question est de savoir comment gérer le cache sur une app Rails sur un site nécessitant une authentification. Car je ne peux pas laisser l'app sans cache sans perdre énormément en perf par rapport à la version PHP actuelle.

Pour info le site tourne avec CakePHP 2.X, lorsuq'une page est appellée le framework va être éxécuté et générer
un fichier PHP simple (ne contenant que des $_SESSION and co pour que le prochain appel soit ultra rapide.

J'ai beau chercher un peu partout je ne trouve pas d'article expliquant comment utiliser un cache dans ce genre de situation. Par exemple je tombe sur du russian doll caching mais cela se base sur les timestamps des enregistrement SQL du coup ça oblige quand même à faire le requête donc je n'en vois pas le bénéfice :(

3 réponses


Pourquoi tu ne fais pas simplement du SQL Caching ? Comme ça, au niveau de tes vues, tes variables ne bougent pas mais cela évite de relancer à chaque fois toutes les requêtes. Tu peux en mettre quelques unes (venant d'un controlleur spécifique) et pas les autres, comme ça tu ne perds pas en capacité, non ?

Genre un truc comme ça :

@categories = Rails.cache.fetch('categories', :expires_in => 24.hours) { Category.joins(:posts).select('distinct categories.*').order('label') }

Ouep c'est une piste mais si je dois faire ça partout ça va être l'anarchie à nettoyer à chaque update ^^

Non mais au niveau des updates, tu utilises une requête standard. Seulement, quand tu sais que tu vas devoir effectuer toujours la même requête et que tu ne ressens pas le besoin de réactualiser les données reçue à chaque appel de page, tu fous la requête en cache.

Exemple :

Tu souhaites afficher les catégories sur une page. Sauf que tu ne veux pas faire une requête SQL à chaque fois qu'un utilisateur arrive sur la page (oui, je sais que tu connais la principe du cache mais bon, d'autres personnes peuvent être intéressées). Dans ce cas là, au lieu de cacher une petite partie de template, tu caches directement la requête SQL. En effet, tu perdras toujours quelques millisecondes quand ton serveur va recharger ta page étant donné qu'il doit régénérer toute la partie HTML mais tu gagneras peut-être en secondes sur la partie SQL, qui n'aura pas l'utilité d'exécuter une nouvelle requête si les données sont en cache. Je pense que ça peut être une bonne possibilité. Par contre, si tu effectues un update, tu devras attendre le temps précisé avant que le serveur ne revoit la requête actualisée... Ou bien peut-être que tu peux utiliser une petite fonction pour supprimer le cache et qu'il se réactualise (les signaux, par exemple) - peut-être même que c'est géré en natif aussi.

Tu pourrais appeler une commande RoR (celle qui supprime le cache) à chaque fois qu'un nouvel enregistrement est capté :). Ce n'est pas si compliqué à mettre en place et ce serait plutôt logique si tu veux que ton nouvel enregistrement soit disponible dès qu'il est posté (et non pas attendre le temps restant avant que le cache ne soit de nouveau rafraichi...).

Après, si tu souhaites mettre en cache le template, directement pour obtenir une réponse sans perdre des centièmes de secondes, tu as toujours cette possibilité : https://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works. Je sais que ce genre de système est utilisé sous Django (Python), où tu peux mettre en cache directement l'include de templates, le templates lui-même, juste une variable...