Carnet Wiki

Découvertes faites avec XRay

Version 9 — 1 month ago 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->https://code.spip.net/autodoc/tree/ecrire/inc/utils.php.html#function_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. Comment cela se peut il ? En relation avec l’alea_ephemere ?

Attention avec les compositions

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.

{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 des inclusions dynamiques

L’inclusion d’un squelette statique dé-dynamise tous les caches des inclusions dynamiques faites par ce squelette.
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 ?
-  Ça me semble plus un bug qu’un feature. La gravité est limitée car on maîtrise en général bien les situations d’inclusion statique (et on peut les limiter).
-  Si c’est un feature ou si c’est pas possible de remettre ça en cause, on pourrait 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.

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 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

Bug SPIP (corrigé) : Contamination des caches non 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ûement, 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 sur le trac
-  L’analyse