Carnet Wiki

Compléments CacheLab et todo

Notes de développements
Voir aussi
-  API CacheLab 1. Action sur des caches ciblés
-  En prime : CacheLab étend #CACHE et INCLURE
-  Archives : statistiques cachelab
-  XRay, un explorateur des caches SPIP

todos

Passage en « test »

- NOMMAGE : Éviter le mix anglais français à l’intérieur d’un même sous-ensemble de vocabulaire : action, index des conditions et options, noms de fonctions, etc. Si possible en français. Par exemple il reste ’list’ dans les arguments et indexes d’options et conditions.
- DOC publier ce qui est stable et mettre à part l’API 2 grand public dont la partie existante est appelée à évoluer et pour laquelle il y a bcp de devs envisageables.

En ensuite

- DEV un argument assert-session pour les INCLURE acceptant les valeurs oui, non, anonyme, oui_login et oui_anonyme comme l’argument de #CACHE, mais fonctionnant comme duree-cache.

- EXEMPLE  : une méthode filtre de #CACHE pour une page « mon_compte » dont la durée de cache soit très courte ou nulle si c’est l’auteur concerné qui visite la page, et longue sinon.

- CLEAN : utiliser spip_timer plutôt que la lib/microtime

- DEV : créer fonction cachelab_menage($pourcent=20) qui détruit les plus vieux caches qui servent le moins (nbhits à 0 ou les plus faibles) afin de libérer de la place. En effet, APCu vide tous ses caches d’un coup en cas de manque mémoire et on peut préférer éviter cela. Il faudra anticiper en suivant le taux de remplissage du cache.
Exemple dalgorithme : s'il reste moins de 20% d'espace, parcourir les 50% plus vieux caches, et parmi ceux-ci, détruire les 50% moins utilisés.

- 2e niveau « usage par non programmeurs » :
-  documenter le début de 2e niveau existant
-  étudier les usages de ce 2e niveau (cf plus bas) pour définir une nouvelle API + tester sur différents jeux de squelette + faire la nouvelle doc
= manière facile (formulaire de config ou defines php) de choisir, activer et configurer une stratégie globale ou spécifique d’invalidation adaptée à un squelette ou à un plugin utilisé + permettre d’activer une stratégie (ou quoi d’autre ?) localement dans un squelette via une balise SPIP dans un squelette

  • par un plugin (ex : ’recalcul’ ; ou plugin « favori » ; ou potentiellement Spipr ou Escal ou SC)
  • ou selon les indications d’une configuration (Config « Basique » : si on reçoit id='typeobjet/valeuridentifiant' on appelle cachelab_cibler('del',  ['cle_objet'=>typeobjet, 'id_objet'=>identifiant]); ; Config « Z » : appeler cachelab_cibler('del',  ['chemin'=>'liste']); en plus. etc).
  • par détection automatique de la présence d’un autre plugin.
  • de manière extensible par les plugins.
    La question de « où mettre ces surcharges » se posera comme pour les codes de IEConfig qui peuvent soit aller dans les squelettes spécifiquement ciblés, soit aller dans le code de ieconfig.

Sous-listes de caches

Sur nursit, les caches APC de plusieurs sites indépendants sont mutualisés et sont accessibles (cryptés) à chaque site. C’est pareil sur gandi.net pour les différents sites hébergés sur un même compte Simple Hosting.
Du coup, leur nombre peut être plus grand et le parcours de tous les caches peut devenir trop long.
-  existe t il une fonction plus efficace de parcours filtrant dans l’API APCu, qu’on puisse utiliser ?
-  ou sinon créer et gérer des sous-listes de caches, elles-même mises en cache. Il y aurait une liste par site et le filtrage ne serait (quasiment) pas plus long que si les caches n’étaient pas mutualisés.

Cette gestion de sous-listes présente d’autres intérêts :

  • À l’intérieur d’un même site, ça pourrait aussi potentiellement accélérer le parcours du cache, de même que le fait la division du répertoire de filecache en sous-répertoires.Mais pour cela, on ne peut pas choisir à quelle liste un cache appartient de la même manière que filecache le fait (= sans sémantique en rangeant les caches en 16 ou 256 répertoires), car quand on fait une requête d’invalidation, on cible un contexte et non un cache précis, et les cibles peuvent appartenir à des dossiers différents. C’est donc la sémantique et le contexte qui doivent aussi définir à quel liste un cache appartient. Il faut pouvoir définir et référencer ses propres contextes spécifiques. Par exemple : « le public » ou « le privé ». Ou bien plus simplement « les caches associés principalement à un ARTICLE » ou « les caches associés principalement à une RUBRIQUE » ou bien « les caches associés à un FAVORI » : une sous-liste par type d’objet.
  • Cette gestion de sous-listes pourrait être faite également pour les autres systèmes de mémoization mémoire : memcached redis etc, ce qui leur permettrait ensuite d’utiliser ensuite le CacheLab, car ce qui les en empêche actuellement, c’est qu’AFAIK il n’y a pas de liste des caches.

Voir aussi plus bas : Extension envisageable : listes ciblées préfiltrée.

-   ANALYSE : pipeline pre_edition et post_edition : confirmer l’exemple théorique d’emploi sur des objets standards, sans redéfinir les fonctions CVT, mais avec les pipelines pre_edition et post_edition + donner un exemple dans la doc. (Mais qu’est ce que ça donne de plus par rapport à la surcharge de suivre_invalideur ? Peut être ça permet d’accéder à plus d’éléments du contextes, qui manqueraient dans le parm ’condition’ reçu par suivre_invalideur ?)

-   SYNTAXE :#CACHE ne peut pas recevoir plusieurs arguments de type ’filtre’ car il n’y a qu’une entête X-Spip-Filtre-Cache. On ne peut donc pas cumuler un log, un assert et un filtre maison. Soit tant pis faut choisir, soit faut se créer un filtre maison qui fait la combinaison voulue, soit faut améliorer ça.

-  DEV : var_mode=cache
⋅ Le core empêche l’emploi de var_mode=cache pour des visiteurs non identifiés alors on teste aussi var_cache mais var_cache ne fait rien souvent mais pas toujours ! Pourquoi ?
⋅ Et pourquoi l’affichage ne se fait il pas qu’au recalcul quand on est logé alors que c’est dans maj_invalideur ? Quand on est pas logé, il ne se fait qu’au recalcul.

Explorer

Cerdic sur contrib « Si il y a ce problème récurrent [avec le formulaire] c’est parce que le formulaire a perdu son dynamisme et le jeton est mis dans le cache au lieu d’être calculé à chaque affichage du formulaire. C’est donc un problème de structure de squelette, et d’utilisation abusive de #INCLURE qui par construction transforme en texte/html tout ce qui est inclus (en perdant donc les partie dynamique) Il faut donc remplacer les #INCLURE par des car vous avez sinon le risque de divulger du contenu saisi par une personne à d’autres personnes… (ou alors le formulaire est inclus via un modèle perso ce qui produit le même résultat) ». Qu’en dit Xray ?

Notes sur l’implémentation

Caches ’aliens’ et autres non traités
APC Cache gère les caches de SPIP pour ce site, mais aussi, selon la configuration serveur, les caches APC d’autres origines. Ces caches APC peuvent être créés et gérés par :
-  d’autres sites SPIP ou non SPIP sur le même serveur si celui ci communalise le cache APC (n*t)
-  ce même site SPIP mais interrogé sur un autre port (car le _CACHE_NAMESPACE, qui pour Memoization identifie le site, est basé notamment sur le port). Ça se produit par exemple si votre site mélange les accès http et https.

Parmi les caches APC autochtones, un certain nombre de caches APC ne sont pas créés pour des squelettes : il y a notamment les caches des déclarations textwheel. Ces caches ne sont pas traités par cacheLab.

API de 3e niveau : usage par non programmeurs = action sur squelettes dist, plugins, objets et formulaires standards

Il semble assez facile de déployer une stratégie optimisée dans le code php qui implémente un objet lorsque ce code est conçu « sur mesure » pour un site donné. Ça semble plus difficile pour des objets génériques qui ne préjugent rien du contexte d’utilisation. La stratégie par défaut de SPIP à l’heure actuelle reste peut être bien la meilleure dans ces cas là.

Un entre-deux semble envisageable pour les squelettes généralistes de SPIP : dist, spipr, escale, SC, sarka... Certains se prêtent certainement bien à l’élaboration d’une stratégie optimisée de ciblage.

On pourrait également définir des conventions génériques de nommage des dossiers et fichiers permettant d’implémenter des régles standard de filtrage et invalidation ciblée du cache. Sur la base de ces conventions, on pourrait définir un plugin standardisé auquel auraient recours les squelettes se conformant aux conventions et souhaitant bénéficier de l’invalidation sélective du cache.

Exemple de règles :
-  nom de dossiers contenant ’liste’, ou plus précisément ’liste_monobjet’, pour les noisettes qui présentent des listes de monobjet et qui doivent être invalidées lorsqu’on crée, supprime ou modifie un monobjet
-  noms de squelettes contenant ’monobjet’ lorsqu’il faut filtrer pour les invalider sélectivement lorsqu’on crée, supprime ou modifie un monobjet avec un id_monobjet particulier

De même, il semble intéressant de chercher à fournir des comportements optimisés standard pour certains plugins :
-  mesfavoris
-  gis
-  formidable ?

DEV : Autres explorations

Extension envisageable : listes ciblées préfiltrées

Une possibilité serait de constituer des listes ciblées : sous-ensembles pré-filtrés de caches. Une telle liste de caches serait alimentée au moment de la création d’un cache, lorsque ce dernier satisfait les critères définissant la liste. L’invalidation sélective pourrait alors directement spécifier les caches de quelle liste doivent être invalidés, en paramètre de suivre_invalideur.
-  Il y aurait un surcoût lors de la création d’un cache, pour préfiltrer le cache. Mais ce surcoût semble très réduit.
-  Les temps d’invalidation seraient alors énormément réduits (divisés par un facteur 100 ou 1000 ?), puisqu’il n’y aurait aucun pré-filtrage requis dans le cas où on demanderait à effacer toute la liste.

Cette possibilité serait particulièrement intéressante pour filecache, lorsque le cache se fait sur le disque car le parcours de tous les fichiers de cache sur le disque est trés coûteux.

Voir le rapport avec le plugin microcache.

Ajouter un ou des pipelines

S’ils étaient implémentés dans le core, dans les fonctions de gestion du cache, des pipelines permettraient d’implémenter des stratégies alternatives de fonctionnement du cache, sans surcharger tout le fichier dans un plugin.
-  suivre_invalideur
-  la fonction qui vérifie si un cache existe et est à jour

Cachecool

On pourrait au contraire souhaiter garder les caches invalides et les utiliser à la demande, comme fait cachecool. Cela n’atténue pas la charge sur le serveur, mais ça donne l’impression d’un service plus rapide.

On peut combiner :
-  les caches périmés sont supprimé par cron toutes les X minutes
-  dans l’intervalle, les caches périmés sont quand même servis. L’utilisateur doit être averti qu’il doit parfois attendre un peu pour que les affichages soient mis à jour ou disposer d’un bouton pour forcer la mise à jour de la noisette qui l’intéresse !

Extension envisageable : un bouton pour désactiver temporairement l’invalidation

Si on procède à une mise à jour importante du site, d’un bloc, il peut être pertinent de bloquer temporairement l’invalidation, puis de tout invalider d’un bloc à la fin de la mise à jour. Ce qui permet aux personnes consultant le site en même temps d’avoir un cache certes datés, mais pas recalculer au fur et à mesure que l’on modifie le site.

Note sur l’emploi pour les modèles

Un modèle n’a pas de cache propre. Le résultat du modèle est automatiquement mis dans le cache de la page appellante.
Par conséquent, si la modif de base impacte le résultat du modèle et qu’on souhaite que cela soit visible tout de suite il faut
-  soit invalider tout le cache si on ne sait pas d’avance où le modèle peut être appelé
-  soit invalider seulement les pages où le modèle peut être appelé si l’on est sur que notre contenu éditorial suit une règle simple. Exemple : un modèle qui afficherait les prochains evenement associés à un article, on sait que notre site ne l’appel que sur la page d’article. Exemple dans un site spipr.

		cachelab_cibler('del',
			array('chemin' => 'content/article',
			'cle_objet' => 'id_article',
			'id_objet' => $id_article,
			'methode_chemin' => '==',
			)
		);// invalider l'id_article


-  soit faire un modele qui ne fait qu’appeler un <INCLURE> dynamique. Et on peut alors cibler les caches de cet inclusion.

Note sur l’emploi avec Formidable

Si l’on souhaite invalider le cache d’un formulaire Formidable (dont une partie peut être construit à partir du contenu de la base de donnée). Il faut invalider
1. Le squelette formulaire/formidable
2. Le squelette inclurer/generer_saisies
3. Le squelette saisies/_base (à vérifier)
4. Le squelette saisies/nomdelasaisie + le cas échéant les squelettes appelé par cette saisie.

JLuc - Mise à jour :30 décembre 2019 à 12h18min