Carnet Wiki

Les enseignements de XRay

Version 16 — Mai 2022 JLuc

Peu avant le Siècle des Lumières, « les cabinets de curiosités faisaient découvrir le monde, y compris lointain (dans le temps et l’espace) et permettaient de mieux le comprendre, ou de confirmer des croyances de l’époque » (wikipedia). Plus tard, le microscope a permis de mieux connaître les forces de la Vie et la biologie de nos cellules, et le téléscope a permis de mieux comprendre les lois de l’Univers et du Cosmos.

De même, le plugin Xray révèle aujourd’hui l’intime fonctionnement des inclusions de squelettes et des caches SPIP, dans toute leur magie et leur complexité... Xray est ainsi bien utile pour débuguer un jeu de squelettes récalcitrant ou pour optimiser un site, mais cela a également permis quelques découvertes, fondamentales ou anecdotiques, sur le fonctionnement de SPIP.

Voici donc un cabinet de curiosités des découvertes faites avec xRay.

Le talon des squelettes sessionnés

Savez vous que les caches sessionnés ont un « talon » ? Ce talon, c’est un stub, un garde-place, un cache creux, sans suffixe _ ni contenu html et qui ne comprend comme métadonnées que l’invalideur session='' et lastmodified. Les talons sont gérés comme les caches mais ce ne sont pas des caches de squelette. Ce sont des marqueurs de sessionnage : ils servent uniquement à indiquer que les caches de ce squelette sont sessionnés. Le source est là : creer_cache et public_cacher.

Ces talons étant vides, c’est un autre cache qui contient le contenu sessionné et les métadonnées du squelette : cet autre cache a l’identifiant de session comme suffixe, ce qui permet de le reconnaître.
Xray permet de filtrer pour ne voir que les talons, et propose des liens pour accéder à la liste de tous les caches ayant le même talon.

Attention à l’explosion : il y a autant de talons qu’il y a de couples (squelette, contexte), et pour chacun de ces talons, il y a autant de caches qu’il y a de sessions. Si vous avez une noisette sessionnée, utilisée pour beaucoup d’objets et par beaucoup d’utilisateurs, il est possible que le cache sature et ne serve plus à rien.

Identifiants de session

Les sessions ont un identifiant = une suite de 8 caractères hexadécimal, calculé par spip_session. Par exemple 654b5de7. Cet identifiant est utilisé, pour les caches sessionnés, en suffixe du nom du talon, et permet à xray de retrouver les caches sessionnés d’un même utilisateur.

Il arrive toutefois que les sessions d’un même utilisateur aient 2 identifiants de session. (Peut être En relation avec l’alea_ephemere a changé entre temps ?) Comment cela se peut il  ?

Effets des compositions et zcore

Les squelettes des compositions sont appelés par l’inclusion d’un autre squelette avec un argument composition en plus. Le cache résultant a le nom du squelette principal, mais la valeur du squelette associé (champ ’source’ du cache) est le squelette de la composition.

Zcore produit également le même type de phénomène.

Hypothèse : c’est l’emploi du pipeline styliser qui provoque cela.

Durée du cache mémoizé

Lorqu’un cache est spécifié explicitement pour une page (par #CACHE{1001}), alors le cache APCU est créé avec une durée plus longue de 1 heure (4601 secondes dans l’exemple).

Lorsque le cache APCU est périmé, il reste dans le cache APCU. Par défaut, la fonction < code>cachelab_cibler</code > (définie cachelab_cibler ( définies par cachelab) efface ces caches périmés, sauf si on lui passe l’option ['clean' =>false ]. XRay, devant pouvoir examiner les caches « dans l’état où ils sont dans la nature », ne fait pas le ménage des caches périmés.

{env} démultiplie t il utilement les caches ?

L’argument d’inclusion {env} transmet à l’inclusion toutes les valeurs de l’environnement du squelette appelant. S’il y en a beaucoup, et que ces valeurs sont indépendantes les unes des autres ou sont exposées au public en tant que variable d’url, alors la combinatoire peut être énorme.

Dans ce cas, il faut donc se poser la question : est-ce que toutes ces combinaisons de valeurs sont réellement utiles ? A t on vraiment besoin de transmettre tous les arguments ?

En particulier, les caches associées à un objet éditorial reçoivent des arguments « date » et « date_default » : est il nécessaire de les transmettre à l’inclusion ? Car ces valeurs étant différentes pour chaque objet, ça empêche de mettre les caches en commun, ce qui sans cela serait possible... si l’inclusion n’a pas besoin d’autres valeur dépendant du dit objet éditorial.

Et si vous utilisez un squelette Z, est-il utile de transmettre « type-page » ?

En combinant simplement ces arguments largement répandus et s’il y a 1000 objets (et donc autant de paire « date+date-default ») et 10 type-pages, cela fait 10000 caches différents !

Si la noisette inclue n’a pas besoin d’accéder à toutes ces valeurs, vous pouvez les annuler pour l’inclusion :
<INCLURE{fond=inclure/mapetitenoisette, env, date='', date_default='', type-page=''}>
Ainsi, avec les nombres exemples donnés plus haut, au lieu de calculer 10000 caches, un seul sera calculé et réutilisé 10000 fois plus souvent. Et le volume du cache sera d’autant allégé, ce qui est encore plus appréciable si vous utilisez la mémoization.

 ! Dé-Dynamisation Dé-Dynamisation des inclusions dynamiques  ! dynamiques

L’inclusion d’un squelette statique (y compris un modele) dé-dynamise tous les caches des inclusions dynamiques faites par ce squelette. En fait, tout code php contenu dans une inclusion statique (code php inline ou inclusion dynamique) est exécuté et c’est le résultat qui est inclu.

Exemple : Si A #INCLUE B qui <INCLUE> C, alors C est en fait inclu statiquement dans B et donc dans A. Une conséquence est que si C est sessionné, alors B et A le sont aussi (confirmation par Cerdic).

Bug ou Feature ?
-  La gêne éventuelle est limitée car on maîtrise en général bien les situations d’inclusion statique et on peut les limiter
-  On pourrait peut être concevoir une nouvelle syntaxe permettant des inclusions superdynamiques, c’est à dire que ces inclusions ne seraient PAS dé-dynamisées lorsque le squelette incluant est inclu statiquement. Ça fait partie des pistes de développements futurs pour le plugin macrosession).

Quand un modèle sessionné est inséré dans le champ éditorial d’un objet

Quand un modèle sessionné est inséré dans le champ éditorial d’un objet, c’est le squelette affichant ce dernier qui est sessionné. L’inclusion du modèle est statique, pareil qu’avec #INCLURE. Le modèle n’a pas de cache du tout. Normalement, on peut avec SPIP3 spécifier une durée de cache pour le modele, mais avec SPIP 3.1.8 je ne vois aucun effet sur la durée du cache du squelette incluant donc je me demande si ça marche ou comment ça se passe.

Squelettes Les squelettes appelés comme en tant que page d’une url

Les squelettes appelés comme en tant que page d’une url se distinguent de ceux appelé via un INCLURE : leur nom de cache se termine en plus par un suffixe. Au minimum ce suffixe est un simple /, mais d’autres chaînes chaines sont possibles. Le même squelette, appelé par un INCLURE, n’a pas ce / à la fin, même s’il a le même environnement.

Le suffixe semble être une sorte de slug relatif à l’url utilisée pour l’affichage de la page : par exemple /spip ou /1234 où 1234 est le N° de l’objet éditorial :
-  ...8b79-gis_json/spip pour le cache de gis_json.html
-  ...928-compte/spip
-  ...f921a-saisies.css/spip
-  ...fe22-mestrucs/spip
-  ...a40f-backend/spip
-  ...a12b-untruc/1234

C’est une zone encore mal cernée. Comme ça dépend des squelettes, XRay utilise un algorithme basique par défaut, mais permet de définir une fonction qui permet de reconnaître lorsqu’un cache correspond à une page et non une inclusion.

process_ins n’est utilisé qu’une fois

L’examen du code montre que si process_ins est ajusté en plusieurs endroits du code, il semble n’être utilisé qu’en un seul endroit : dans sandbox.php. Ne pourrait-on pas ne le calculer que sur son unique endroit d’utilisation ? Ça allégerait le code et les données mises en cache.

Bug SPIP # 4235 ( corrigé )  : Contamination des caches non sessionnés ( corrigé )

sessionnés

Si dans un squelette ya une suite d’INCLURE dynamiques non sessionnés avec au milieu d’eux un inclure sessionné, plusieurs inclusions après l’inclure sessionné étaient aussi, indûment, sessionnés. D’autres types de circonstances provoquaient la création de caches sessionnées alors qu’ils ne devraient pas l’être, et induisant une explosion du cache, nuisant aux performances du site.

Ce bug n’impactait que les sites ayant au moins un cache sessionné, c’est à dire une #SESSION, un #AUTORISER, un #URL_ACTION_AUTEUR, un #BOUTON_ACTION dans un squelette, qui contaminait le reste des caches en en forçant le sessionnement.

XRay a permis de détecter ce bug qui était passé inaperçu, quand bien même il nuisait aux performances des sites, et a également facilité la mise au point de la correction. La correction a été intégrée dans spip 3.3 dev.
-  Le ticket

Bug SPIP #5156 : tout spip_meta va dans #CONFIG (corrigé)

L’examen des caches a révélé que tout spip_meta se retrouvait inutilement dans l’environnement de certains formulaires et donc dans les fichiers de cache : ticket #5156

La correction dans SPIP 4.2 se fait dans plusieurs commits :
-  pour spip : https://git.spip.net/spip/spip/commit/720ef6ca3d0876e287626f6895e48c2cef883d7b
-  pour les plugin-dist : https://git.spip.net/spip/sites/commit/278b099ccdd3ddb0874783cb1992f52c7cc6ef35, https://git.spip.net/spip/mots/commit/c1db2a099e2b316f299086f02f9853d2bcd06cff, https://git.spip.net/spip/breves/commit/643bfce1e9aa221289561725d5e5c5844878aeb8, https://git.spip.net/spip/svp/commit/b686c0702b99fcd1fbf61e8f3cd801fe07f48bc1