ENbext.dev
DocumentationInclusions côté serveur

Traduction automatique depuis l’anglais. Consulter l’original.

Sur cette page

Mise en cache adaptée aux variations

Certaines inclusions ont le même src mais un contenu différent selon la personne qui le demande. Le tableau des tarifs présente différents forfaits pour les administrateurs par rapport aux utilisateurs gratuits. Le système de navigation affiche « Tableau de bord » ou « Connexion » en fonction de l'authentification. Le héros est en français pour les utilisateurs français.

L'attribut vary déclare sur quelles dimensions de requête cette inclusion varie. bext calcule la clé de cache à partir du chemin source plus les valeurs de dimension déclarées, produisant un fragment mis en cache distinct par combinaison (dim × dim ×...).

html
<bext-include src="/partials/pricing-table"
  vary="role,locale,geo"
  ttl="10m"
></bext-include>

Même balise HTML. Entrées de cache séparées pour admin/en/US vs viewer/fr/FR vs admin/fr/DE.

Dimensions prises en charge#

Les valeurs proviennent du contexte de la requête, extraites par le middleware bext. Vous pouvez les référencer dans n'importe quelle inclusion vary :

Dimension Source Exemples de valeurs
role Session d'authentification admin, editor, viewer, anonymous
auth Session d'authentification (grossière) authenticated, anonymous
locale En-tête ou cookie Accept-Language en, fr, de, ja
geo En-têtes GeoIP / CDN US, FR, DE, JP
device Classement User-Agent mobile, tablet, desktop
theme Cookie ou en-tête light, dark, auto
currency Session ou géo-dérivé USD, EUR, GBP

Plus toutes les dimensions personnalisées définies dans bext.config.toml :

toml
[include.vary.custom]
"preferred-unit" = { source = "cookie", name = "unit" }
"api-version" = { source = "header", name = "x-api-version" }

Dérivation de la clé de cache#

La clé est un hachage FNV-1a stable de 64 bits de :

code
hash(src || "\0" || sorted_vary_pairs)

Seules les dimensions déclarées dans la liste vary de l'inclusion contribuent à la clé. Une requête avec role=admin, locale=fr, geo=US frappant une inclusion avec vary="role,locale" produit la même clé de cache qu'une requête avec les mêmes role et locale mais un geo différent.

rust
// Request A: role=admin, locale=fr, geo=US
// Request B: role=admin, locale=fr, geo=FR
// Include: vary="role,locale"
// → same cache key (geo ignored for this include)

// Request C: role=viewer, locale=fr, geo=US
// Include: vary="role,locale"
// → different cache key (role changed)

C'est ainsi qu'un élément peut produire N entrées de cache - une par combinaison unique de valeurs qui intéressent réellement l'inclusion.

Contrôle de cardinalité#

Une dimension variable avec trop de valeurs distinctes remplit le cache avec des entrées ponctuelles. Si vous variez sur locale avec 50 paramètres régionaux, vous disposez de 50 entrées de cache. Variez sur locale et role avec 4 rôles, vous disposez de 200 entrées. Ajoutez geo avec 100 pays et vous en avez 20 000.

bext suit la cardinalité et avertit lorsqu'une seule inclusion produit trop de variantes :

code
WARN include vary cardinality: src="/partials/pricing" dim="locale"
     has 47 unique values — consider grouping (en, fr, de, zh, *)

Limitez les variantes par inclusion dans la configuration :

toml
[include.cache]
max_variants_per_include = 100

En cas de dépassement, la variante la plus froide est expulsée du LRU. Cela limite l’utilisation de la mémoire quelle que soit la forme du trafic.

Attention

La cardinalité s'aggrave rapidement : vary="locale,role,geo" avec 50 paramètres régionaux × 4 rôles × 100 pays = 20 000 entrées de cache possibles. Définissez max_variants_per_include dans [include.cache] et préférez les regroupements plus grossiers (par exemple en/fr/de/zh/* ) pour les dimensions à cardinalité élevée.

Les inclusions authentifiées doivent varier#

Si une inclusion contient auth="required" ou role="...", elle doit inclure la dimension appropriée dans vary lorsqu'elle est mise en cache - sinon le cache servirait la barre d'outils d'administration aux utilisateurs anonymes (empoisonnement du cache).

html
<!-- WRONG: admin content will leak to non-admins -->
<bext-include src="/partials/admin"
  auth="required" role="admin" ttl="30m"
></bext-include>

<!-- RIGHT: cached per role -->
<bext-include src="/partials/admin"
  auth="required" role="admin"
  ttl="30m" vary="role"
></bext-include>

bext enregistre un avertissement lorsque les inclusions authentifiées sont mises en cache sans variation de rôle. En mode strict (configurable), le cache est désactivé pour de telles inclusions plutôt que de diffuser un contenu potentiellement erroné.

Conseil

Seules les dimensions répertoriées dans [include.vary.dimensions] (ou [include.vary.custom] ) sont reconnues. Le référencement à une dimension non déclarée dans vary="..." est ignoré en silence : cela ne contribuera pas à la clé de cache.

SSI et ESI#

SSI et ESI n'ont pas d'attribut vary sur la balise. Déclarez plutôt variant dans les règles de configuration :

toml
[[include.rules]]
pattern = "/partials/pricing*"
vary = ["role", "locale"]
ttl = "10m"

Toute inclusion correspondante – bext -native, SSI ou ESI – obtient cette configuration variable.

html
<!-- all three get vary="role,locale" from the rule above -->
<bext-include src="/partials/pricing" ttl="10m"></bext-include>
<!--#include virtual="/partials/pricing" -->
<esi:include src="/partials/pricing" />

Utilisation de la variation dans les résolveurs#

Les résolveurs personnalisés reçoivent les valeurs variables dans le contexte de la demande :

rust
impl IncludeResolver for MyResolver {
    fn resolve(&self, d: &IncludeDirective, ctx: &IncludeContext) -> Option<String> {
        let role = ctx.vary_value("role").unwrap_or("anonymous");
        let locale = ctx.vary_value("locale").unwrap_or("en");
        Some(render_pricing_for(role, locale))
    }
}

Les clés de couche de cache sur ces valeurs sont automatiquement basées sur l'attribut vary de l'inclusion. Le résolveur lui-même les lit simplement.

Dimensions personnalisées#

Ajoutez des dimensions variables spécifiques à la demande dans la configuration :

toml
# Example: vary on a feature-flag cookie
[include.vary.custom]
"beta-features" = { source = "cookie", name = "bext_beta" }

# Example: vary on an API version header
"api-version" = { source = "header", name = "x-api-version" }

Utilisez-les comme n'importe quelle dimension intégrée :

html
<bext-include src="/partials/api-docs"
  vary="api-version"
  ttl="1h"
></bext-include>

Désormais, chaque version de l'API dispose de sa propre copie en cache de la documentation.

Voir aussi#

Modifier cette page ↗Besoin d’aide ? ↗
Rechercher dans la documentation

Saisissez un sujet, une commande ou une question.