Introduction
Une bannière de maintenance doit disparaître lorsque la période d’annonce se termine. Si vous la laissez affichée, les visiteurs peuvent croire qu’une ancienne panne est toujours en cours. Vous allez créer un Worker qui lit un avis dans KV et détermine s’il doit encore être affiché.
Il existe deux dates limites distinctes. Une date limite d’affichage indique à votre code à quel moment il doit cesser d’afficher le message. Une expiration KV indique au service de stockage à quel moment supprimer l’entrée. Vous conserverez volontairement dans le stockage un ancien enregistrement de référence afin de prouver que votre application peut masquer du contenu expiré alors que les données existent encore. Vous observerez ensuite l’expiration automatique d’un second enregistrement dans le KV cloud.
Terminez d’abord Serve Account Preferences. Cette VM indépendante dispose de Node.js 22.22.0 et de Wrangler 4.131.1 installé localement dans le projet /home/labex/project/temporary-notices. Utilisez votre propre compte d’apprentissage ainsi que les mêmes autorisations de lecture du compte, d’écriture des Workers et d’écriture dans KV. Vous allez créer un Worker et un espace de noms temporaires, utiliser uniquement des messages synthétiques et effectuer le nettoyage avant de vous déconnecter. Ce court exercice ne nécessite ni domaine acheté ni mise à niveau payante. Prévoyez environ cinq minutes pour l’observation chronométrée, en plus de l’écriture et des tests du gestionnaire.
Connecter un espace de noms pour les avis
Dans cette étape, vous allez connecter un nouvel espace de noms destiné aux avis temporaires. Utilisez un espace de noms distinct et un nom de Worker unique afin que vos essais sur l’expiration ne puissent pas supprimer les données d’une autre application. La liaison NOTICES connectera votre gestionnaire à cette ressource.
Accédez au projet préparé :
cd /home/labex/project/temporary-notices
Générez une fois un nom unique. openssl rand -hex 6 affiche un suffixe aléatoire ; $(...) l’insère dans le nom. La variable du shell conserve ce nom pour les commandes suivantes dans ce terminal.
WORKER_NAME="labex-notices-$(openssl rand -hex 6)"
printf '%s\n' "$WORKER_NAME"
Autorisez cette VM. En plus de lire l’identité de votre compte, l’autorisation Workers Scripts Write permet le déploiement et la suppression, tandis que Workers KV Write permet de gérer l’espace de noms et les clés de cet exercice.
npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_kv:write
Ouvrez dans votre navigateur le lien vers l’appareil affiché, saisissez le code actuel, vérifiez les autorisations demandées et le compte d’apprentissage, puis autorisez Wrangler. Un accès en arrière-plan peut également apparaître sur la page de consentement. Revenez au terminal et attendez la fin de la connexion.
Vérifiez les mêmes autorisations d’écriture pour les Workers et KV que celles introduites dans Create a Feature Flag Store. Confirmez votre compte d’apprentissage avant d’autoriser l’opération.
npx wrangler whoami --json
Vérifiez que loggedIn: true est présent ainsi que le name du compte d’apprentissage, même si un seul compte est affiché. Copiez l’id de ce compte. Enregistrez-le dans la configuration ci-dessous en remplaçant YOUR_ACCOUNT_ID avant d’exécuter la commande. Le document here de cat écrit dans un fichier tout le contenu situé entre les deux lignes JSON ; > remplace le fichier. Le délimiteur non entouré de guillemets permet au shell d’insérer $WORKER_NAME.
cat > wrangler.jsonc <<JSON
{
"name": "$WORKER_NAME",
"main": "src/index.js",
"compatibility_date": "2026-07-30",
"account_id": "YOUR_ACCOUNT_ID",
"workers_dev": true
}
JSON
Créez un espace de noms dans ce compte. Son titre reprend le nom unique du Worker afin que vous puissiez reconnaître cette paire plus tard. --update-config=false laisse la modification de la liaison visible afin que vous puissiez l’effectuer vous-même, au lieu de modifier automatiquement le fichier.
npx wrangler kv namespace create "$WORKER_NAME-notices" --update-config=false
La sortie contient l’ID du nouvel espace de noms. Copiez-le, puis remplacez YOUR_ACCOUNT_ID et YOUR_NAMESPACE_ID dans cette configuration complète. Le nom de liaison NOTICES est celui que votre code utilisera ; l’ID identifie la ressource Cloudflare réelle.
cat > wrangler.jsonc <<JSON
{
"name": "$WORKER_NAME",
"main": "src/index.js",
"compatibility_date": "2026-07-30",
"account_id": "YOUR_ACCOUNT_ID",
"workers_dev": true,
"kv_namespaces": [
{ "binding": "NOTICES", "id": "YOUR_NAMESPACE_ID" }
]
}
JSON
npx wrangler kv namespace list
Repérez le titre de l’espace de noms de cet exercice et comparez son ID avec celui du fichier. D’autres espaces de noms peuvent être présents ; ne les modifiez pas. Cette configuration indique quel compte et quelle ressource les commandes suivantes doivent utiliser. Une liaison est une référence vers un espace de noms, et non une copie de ses données.
Masquer un ancien avis avant de supprimer ses données
Dans cette étape, vous allez séparer le comportement d’affichage du nettoyage du stockage. Un horodatage est un nombre qui représente un instant. Ici, displayUntil utilise des secondes Unix, comptées depuis le début de l’année 1970 en UTC. Date.now() renvoie des millisecondes ; le gestionnaire les divise donc par 1000 avant de les comparer. Utiliser la même unité évite une erreur fréquente dans le calcul des dates limites.
Écrivez le gestionnaire avec ce document here entre guillemets :
cat > src/index.js <<'JS'
export default {
async fetch(request, env) {
const url = new URL(request.url);
const key = url.searchParams.get("key") ?? "notice:maintenance";
if (url.pathname !== "/notice" || !/^notice:[a-z]{1,20}$/.test(key)) {
return new Response("Not found", { status: 404 });
}
let entry;
try {
entry = await env.NOTICES.getWithMetadata(key, "text");
} catch {
return Response.json({ error: "Notice storage unavailable" }, { status: 503 });
}
if (entry.value === null) {
return Response.json({ visible: false, reason: "missing" });
}
let notice;
try {
notice = JSON.parse(entry.value);
} catch {
return Response.json({ visible: false, reason: "invalid" });
}
if (!notice || typeof notice.message !== "string" || !notice.message.trim() ||
!Number.isSafeInteger(notice.displayUntil) || notice.displayUntil <= 0) {
return Response.json({ visible: false, reason: "invalid" });
}
if (Math.floor(Date.now() / 1000) >= notice.displayUntil) {
return Response.json({ visible: false, reason: "expired" });
}
return Response.json({
visible: true, message: notice.message,
kind: entry.metadata?.kind === "maintenance" ? "maintenance" : "general"
});
}
};
JS
Le paramètre de requête key sélectionne un avis synthétique ; s’il est absent, le gestionnaire utilise notice:maintenance. L’application masque les avis absents, mal formés ou expirés et renvoie une réponse JSON qui explique la raison. Une erreur de lecture KV renvoie 503 au lieu de faire croire que l’avis est absent. Le champ de métadonnées kind indique la catégorie de l’avis ; des métadonnées absentes ou inattendues entraînent l’utilisation de general.
La comparaison de la date limite utilise >= : l’avis est masqué à la date limite, et non une seconde plus tard. Cette vérification est exécutée à chaque requête. Une page web qui a déjà affiché une bannière devrait également s’actualiser ou la supprimer avec son propre minuteur ; la réponse d’un Worker ne peut pas modifier seule une page déjà rendue.
Enregistrez localement un ancien avis de référence. La date limite 1 correspond à un instant connu de l’année 1970 ; cet enregistrement est donc déjà expiré du point de vue de l’application. Nous omettons volontairement toute expiration KV afin que l’enregistrement reste disponible pour inspection.
npx wrangler kv key put notice:reference '{"message":"Old maintenance notice","displayUntil":1}' --binding NOTICES --local --metadata '{"kind":"maintenance"}'
npx wrangler dev --local --ip 0.0.0.0 --port 8080 > local.log 2>&1 &
DEV_PID=$!
cat local.log
Le serveur exécuté en arrière-plan écrit sa sortie dans local.log. Répétez la commande d’affichage du journal jusqu’à ce qu’elle indique que le serveur est prêt sur le port 8080. Demandez ensuite l’ancien avis de référence :
curl -i 'http://127.0.0.1:8080/notice?key=notice:reference'
Vous devez obtenir HTTP 200 et {"visible":false,"reason":"expired"}. Les guillemets empêchent le point d’interrogation de l’URL d’être interprété par le shell comme une syntaxe de nom de fichier. Prouvez que l’entrée existe toujours :
npx wrangler kv key get notice:reference --binding NOTICES --local --text
Le JSON est toujours présent. C’est votre code, et non une suppression automatique, qui a empêché l’ancien avis d’être affiché. Une clé absente doit également être traitée correctement :
curl -i 'http://127.0.0.1:8080/notice?key=notice:missing'
Vous devez obtenir {"visible":false,"reason":"missing"}. Laissez le serveur local s’exécuter jusqu’au nettoyage.
Publier un avis avec deux dates limites
Dans cette étape, vous allez d’abord publier le Worker, puis démarrer une courte période d’affichage dans le cloud. Préparer le point de terminaison avant de démarrer le compte à rebours vous laisse le temps d’inspecter le résultat actif.
Créez la même référence sans expiration dans l’espace de noms distant :
npx wrangler kv key put notice:reference '{"message":"Old maintenance notice","displayUntil":1}' --binding NOTICES --remote --metadata '{"kind":"maintenance"}'
npx wrangler deploy
Vérifiez le nom du Worker généré et la liaison NOTICES, puis enregistrez l’URL publique réelle indiquée dans la sortie :
WORKER_URL="https://YOUR_WORKER.YOUR_SUBDOMAIN.workers.dev"
curl -i "$WORKER_URL/notice?key=notice:reference"
L’ancienne référence doit être masquée avec la raison expired. Si le nom d’hôte n’est pas encore prêt, attendez puis réessayez avant de commencer la partie chronométrée. Ne demandez pas encore la clé de maintenance par défaut : les lectures de clés KV absentes peuvent elles aussi être mises en cache.
Lisez les instructions restantes avant d’exécuter les commandes suivantes. date +%s renvoie l’heure Unix actuelle de la VM ; $((...)) effectue un calcul arithmétique dans le shell. Nous cesserons d’afficher l’avis après trois minutes, puis demanderons à KV de le supprimer une minute plus tard.
DISPLAY_UNTIL=$(($(date +%s) + 180))
KV_EXPIRES=$((DISPLAY_UNTIL + 60))
Écrivez la charge utile réelle de l’application. Le délimiteur JSON non entouré de guillemets insère la date limite numérique dans le fichier :
cat > notice.json <<JSON
{"message":"Maintenance starts soon","displayUntil":$DISPLAY_UNTIL}
JSON
--path lit la valeur dans ce fichier. --expiration définit une expiration KV absolue en secondes Unix ; --metadata ajoute la catégorie de l’avis à côté de la valeur.
npx wrangler kv key put notice:maintenance --path notice.json --binding NOTICES --remote --expiration "$KV_EXPIRES" --metadata '{"kind":"maintenance"}'
KV prend également en charge une durée de vie relative, appelée TTL (time to live), exprimée en secondes à partir de l’écriture. Wrangler appelle cette option --ttl ; l’API de liaison l’appelle expirationTtl. Toute expiration, relative ou absolue, doit être située au moins 60 secondes dans le futur. Ici, nous utilisons une expiration absolue afin que vous puissiez comparer directement les deux dates limites. Consultez Options d’expiration KV.
npx wrangler kv key list --binding NOTICES --remote
Repérez notice:maintenance, son expiration et ses métadonnées kind. La référence n’a pas d’expiration KV. Lisez maintenant le message actif :
curl -i "$WORKER_URL/notice"
Vous devez obtenir HTTP 200 et {"visible":true,"message":"Maintenance starts soon","kind":"maintenance"}. Exécutez maintenant la vérification de cette étape, avant la fin de la période d’affichage. Elle vérifie la valeur réelle dans le cloud, les métadonnées, l’expiration KV, la liaison et la réponse active. Un horodatage enregistré seul ne prouve pas que l’avis a bien été stocké.
Si vous manquez cette période, répétez les deux affectations de temps, réécrivez notice.json, puis répétez l’écriture distante avec de nouvelles dates limites. Ne répétez pas rapidement les écritures. Une lecture précédemment mise en cache peut mettre du temps à refléter le remplacement ; tenez-en compte et répétez la vérification active. Continuez uniquement lorsqu’elle réussit.
Après la réussite de la vérification active, ouvrez Storage & databases → Workers KV dans le Dashboard du même compte d’apprentissage et sélectionnez l’espace de noms de cet exercice. Ouvrez KV Pairs et cliquez sur View à côté de notice:maintenance pour examiner le message et displayUntil. Consultez l’expiration KV et les métadonnées dans la liste de clés de la CLI ; cette vue affiche la valeur stockée. Effectuez uniquement des lectures : le temps continue de passer. Si la clé a déjà expiré, passez à l’étape suivante sans la recréer uniquement pour cette vue. Le nom et l’horodatage de la capture sont des exemples à ne pas recopier.

Observer le contenu masqué et l’expiration automatique
Dans cette étape, vous allez observer les deux dates limites sans supprimer manuellement la clé de maintenance. Ne modifiez pas notice.json afin de pouvoir comparer la charge utile d’origine avec le résultat.
Affichez les deux heures prévues ainsi que l’heure actuelle :
printf 'displayUntil=%s
KV expiration=%s
now=%s
' "$DISPLAY_UNTIL" "$KV_EXPIRES" "$(date +%s)"
Attendez que l’heure actuelle atteigne displayUntil. Ces commandes calculent uniquement le délai restant. Si la date limite est déjà dépassée, la condition évite la pause. sleep attend un nombre de secondes ; if empêche de lui transmettre un délai négatif.
WAIT_SECONDS=$((DISPLAY_UNTIL - $(date +%s) + 1))
if [ "$WAIT_SECONDS" -gt 0 ]; then sleep "$WAIT_SECONDS"; fi
curl -i "$WORKER_URL/notice"
Le message ne doit plus être visible. Avant l’expiration KV, vous devez obtenir {"visible":false,"reason":"expired"}. Si vous revenez après l’expiration de la clé par KV, le champ reason peut être missing ; dans les deux cas, l’affichage est empêché. La référence conservée reste une vérification directe du comportement de la date limite de l’application :
curl -i "$WORKER_URL/notice?key=notice:reference"
npx wrangler kv key get notice:reference --binding NOTICES --remote --text
Le point de terminaison masque la référence avec la raison expired, tandis que la lecture KV renvoie toujours son ancien JSON. Cela montre pourquoi la date limite de l’application est utile même lorsque les données stockées restent disponibles.
Attendez maintenant l’heure d’expiration KV :
WAIT_SECONDS=$((KV_EXPIRES - $(date +%s) + 1))
if [ "$WAIT_SECONDS" -gt 0 ]; then sleep "$WAIT_SECONDS"; fi
npx wrangler kv key list --binding NOTICES --remote
curl -i "$WORKER_URL/notice"
La liste ne doit plus contenir que notice:reference ; le point de terminaison par défaut doit renvoyer {"visible":false,"reason":"missing"}. N’exécutez pas de commande de suppression pour la clé de maintenance : cette observation porte sur l’expiration automatique. Si l’entrée reste visible, répétez les vérifications en lecture seule toutes les 15 secondes pendant deux minutes au maximum. Il s’agit d’une fenêtre d’observation pour l’exercice, et non d’une garantie concernant le moment exact de la suppression. Si le résultat ne converge pas, signalez qu’il n’est pas concluant au lieu de déclarer la réussite. Une erreur d’autorisation ou de réseau ne prouve pas l’absence de l’entrée.
L’expiration KV et le cache de lecture sont deux concepts différents. L’expiration s’applique même lorsqu’une durée de cache de lecture plus longue a été demandée. Toutefois, les modifications de la configuration stockée peuvent se propager avec un délai ; une nouvelle date limite écrite après une lecture précédente ne constitue donc pas une garantie immédiate de planification globale. Cet exercice vérifie la date limite contenue dans l’enregistrement effectivement lu par le gestionnaire.
Supprimer les ressources cloud temporaires
Dans cette étape, vous allez supprimer les deux ressources pendant que Wrangler est encore autorisé. Un espace de noms peut continuer d’exister après la suppression de son Worker ; supprimer l’application seule ne nettoie donc pas ses données.
Arrêtez le processus de développement local lancé dans ce terminal :
kill "$DEV_PID"
Inspectez les références de ressources enregistrées avant de supprimer quoi que ce soit :
cat wrangler.jsonc
Vérifiez le nom du Worker labex-notices-... et l’ID de l’espace de noms NOTICES. Supprimez le Worker sélectionné par cette configuration :
npx wrangler delete
Si une confirmation vous est demandée, vérifiez que le nom affiché correspond à cet exercice et confirmez avec y. Supprimez ensuite uniquement l’espace de noms référencé par NOTICES. Cette opération supprime également l’enregistrement de référence conservé :
npx wrangler kv namespace delete --binding NOTICES
Vérifiez l’espace de noms dans toute demande de confirmation avant d’accepter. Conservez wrangler.jsonc intact afin que la vérification indépendante puisse identifier les ressources qui doivent avoir disparu.
npx wrangler kv namespace list
L’espace de noms de cet exercice doit être absent ; les espaces de noms sans rapport doivent rester présents. Actualisez les listes du Dashboard pour confirmer que le Worker et l’espace de noms de l’exercice ont disparu. Une requête échouée ou une session expirée ne prouve pas la suppression. Exécutez la vérification de cette étape avant de vous déconnecter afin qu’elle puisse inspecter un inventaire autorisé.
Terminer l’autorisation de la VM
Dans cette étape, vous allez déconnecter Wrangler une fois la vérification du nettoyage réussie. La déconnexion met fin à l’autorisation Wrangler enregistrée pour cette VM ; elle ne supprime pas les ressources cloud et ne vous déconnecte pas de votre session Dashboard habituelle dans le navigateur.
npx wrangler logout
npx wrangler whoami --json
Vérifiez que le résultat structuré indique "loggedIn": false. Cette commande non authentifiée peut se terminer avec un code de sortie différent de zéro, ce qui est normal ici. Si vous obtenez uniquement une erreur de connexion sans état d’authentification explicite, réessayez lorsque la connexion fonctionnera.
Les fichiers locaux restants et l’état KV local appartiennent à cette VM temporaire. Ils sont distincts des ressources cloud que vous avez déjà supprimées. Vous pouvez maintenant terminer l’exercice.
Résumé
Vous avez créé un lecteur d’avis qui vérifie une date limite d’affichage à chaque requête, traite correctement les données absentes ou invalides et lit une catégorie dans les métadonnées KV. Un ancien enregistrement conservé a prouvé que masquer du contenu ne nécessite pas de le supprimer au préalable. Un second enregistrement a illustré l’expiration KV au moyen d’un horodatage absolu et d’une vérification distincte de la suppression automatique.
Vous avez distingué une date limite d’affichage, une expiration du stockage et le comportement du cache de lecture, puis supprimé les ressources temporaires et vous êtes déconnecté. Ensuite, vous allez importer et gérer un petit catalogue de redirections dans KV.



