ENbext.dev
DocumentationInclusions côté serveur

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

Sur cette page

La mise en cache inclut

Inclut leur propre cycle de vie de cache indépendant de la page. Déclarez une durée de vie sur l'élément et bext stocke le code HTML résolu dans son cache hiérarchisé ; les requêtes suivantes sont diffusées à partir du cache sans appeler le résolveur.

html
<bext-include src="/__bext/nav"
  ttl="5m" swr="1h" tags="chrome"
></bext-include>

La navigation est résolue une fois, servie fraîche pendant 5 minutes, puis servie rassis pendant une heure maximum tandis que bext la revalide en arrière-plan. Marqué chrome afin que vous puissiez invalider tous les fragments Chrome avec un seul appel de purge.

Les attributs#

Attribut Format But
ttl 5m, 1h, adaptive Durée de vie de la fraîcheur du cache
swr 1h, 1d Fenêtre obsolète pendant la revalidation
tags chrome,nav Balises pour invalidation groupée

Syntaxe de durée : 30s, 5m, 1h, 1d ou ms brut (par exemple, 200ms ). Non ttl signifie pas de mise en cache.

Comment fonctionne la mise en cache#

Le cache d'inclusion de bext est un wrapper sur le cache hiérarchisé existant :

code
Request arrives
  ↓
Compute cache key = hash(src, vary_values)
  ↓
L0 (hot map) → HIT: return cached HTML
           → MISS ↓
L1 (mmap)   → HIT: promote to L0, return
           → MISS ↓
L2 (Redis)  → HIT: promote to L0+L1, return
           → MISS ↓
Resolver chain → compute HTML
  ↓
Store in L0 + L1 + L2 with TTL
  ↓
Return HTML
  • L0 est un DashMap par processus – lectures inférieures à la microseconde.
  • L1 est sauvegardé par mmap et persiste lors des redémarrages, de sorte que les caches chauds survivent aux déploiements.
  • L2 est Redis (facultatif) et partage l'état sur des instances à l'échelle horizontale.

Obsolète pendant la revalidation#

Avec swr="1h" :

code
time=0     include resolved, stored in cache (TTL=5m, SWR=1h)
time=4m    request → fresh → return cached
time=6m    request → stale but in SWR window
             → return cached HTML immediately (non-blocking)
             → spawn background task to revalidate
           background task completes → cache updated
time=1h5m  request → expired → cache miss → resolve

L'utilisateur n'attend jamais la revalidation. Le Stampede Guard garantit une seule revalidation en arrière-plan par clé, même en cas de pics de trafic.

Balises de cache#

Les balises vous permettent d'invalider des groupes d'inclusions à la fois :

html
<bext-include src="/__bext/nav" tags="chrome,nav"></bext-include>
<bext-include src="/_partials/footer.html" tags="chrome"></bext-include>

Après avoir déployé un nouveau pied de page :

bash
curl -X POST http://localhost/__bext/cache/purge \
  -d '{"tags":["chrome"]}'

Les deux inclusions sont invalidées. La requête suivante les reconstruit.

Les balises peuvent également provenir de la configuration :

toml
[[include.rules]]
pattern = "/__bext/nav*"
tags = ["chrome", "nav"]

[[include.rules]]
pattern = "/_partials/*"
tags = ["chrome"]

TTL adaptatif#

Utilisez ttl="adaptive" pour adapter la durée de vie du cache en fonction du nombre d'accès :

html
<bext-include src="/partials/homepage-hero"
  ttl="adaptive" swr="1h" tags="homepage"
></bext-include>

La formule (identique au TTL adaptatif ISR) :

code
next_ttl = min(base_ttl * (1 + ln(1 + hits)), max_ttl)

Avec les valeurs par défaut (base=60s, max=600s, seuil=10 hits) :

Nombre de coups TTL efficace
< 10 Années 60 (base)
100 ~337s
1000 ~475s
10000 600s (plafonné)
∞ 600s (plafonné)

Les options les plus populaires incluent rester en cache plus longtemps (meilleur amortissement du coût de résolution). Les inclusions froides expirent à la base TTL (meilleure fraîcheur pour la longue traîne).

Protection contre la bousculade#

Lorsqu'une inclusion à chaud expire et qu'un flot de requêtes simultanées arrive, un seul travailleur se régénère — les autres servent du contenu obsolète (si dans la fenêtre SWR) ou attendent la fin de la première régénération.

rust
pub enum StampedeLock {
    Acquired(token),  // you regenerate
    Waiting,          // someone else is regenerating
}

Cela évite le problème du « troupeau tonitruant » où N travailleurs calculent tous simultanément le même fragment coûteux.

Configuration#

Réglage du cache global :

toml
[include.cache]
enabled = true
l1_max_entries = 5000
l2_prefix = "bext:include:"
max_variants_per_include = 100

[include.cache.adaptive]
base_ttl_ms = 60_000
max_ttl_ms = 600_000
extension_threshold = 10

Valeurs par défaut par source (appliquées à toute inclusion correspondante, y compris SSI/ESI) :

toml
[[include.rules]]
pattern = "/__bext/nav*"
ttl = "5m"
swr = "1h"
tags = ["chrome"]

[[include.rules]]
pattern = "/api/*"
ttl = "30s"
swr = "5m"
timeout = "200ms"

[[include.rules]]
pattern = "/_partials/*"
ttl = "1d"
tags = ["chrome"]

La première règle correspondante gagne. Les attributs de l'élément HTML remplacent la règle.

Conseil

La première entrée [[include.rules]] correspondante gagne. Placez des modèles plus spécifiques (par exemple /api/live/* ) avant les modèles fourre-tout généraux (par exemple /api/* ) afin qu'ils ne soient pas ombragés.

Quand ne pas mettre en cache#

Attention

L'omission de ttl désactive entièrement le cache : le résolveur s'exécute à chaque requête. Pour les données en direct, préférez un court ttl plus swr, ou utilisez Le temps réel inclut au lieu de compter sur la mise en cache zéro TTL.

Certaines inclusions devraient être résolues à chaque demande :

  • Personnalisation par utilisateur sans dimension variable (vous mettriez en cache le contenu d'un utilisateur pour un autre).
  • Données en direct telles que les horodatages actuels, les prix des crypto-monnaies et les cotations boursières. Utilisez plutôt realtime.
  • Opérations ponctuelles comme les jetons CSRF, les noms occasionnels.

Omettez ttl pour contourner complètement le cache : le résolveur s'exécute à chaque requête.

Voir aussi#

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

Saisissez un sujet, une commande ou une question.