documente la capacité, la restauration et le redémarrage (étape 13)

Capacité mesurée sur 20 VM (docs/capacite.md), restauration complète du
portail réussie, retour automatique de tous les services après redémarrage.
Retire l'unité systemd orpheline de ProxySQL, rend fidèle au navigateur la
mesure du temps d'ouverture d'un lab (2,8 s), et regroupe la dette révélée.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-09 20:12:11 +02:00
parent 42884597a9
commit 0a5df89201
8 changed files with 273 additions and 8 deletions

View file

@ -16,6 +16,7 @@ import os
import re
import threading
import time
from concurrent.futures import ThreadPoolExecutor
import requests
import websocket
@ -70,11 +71,14 @@ etat_change.wait(60)
page = eleve.get(f"{BASE}/seances/{seance}/attente-eleve").text
csrf = re.search(r"'X-CSRF-TOKEN': '([^']+)'", page).group(1)
consoles = {}
for url, nom in zip(re.findall(r"fetch\('(http[^']+/console)'", page), re.findall(r'data-onglet="\d+"[^>]*>([^<]+)<', page)):
url = re.sub(r"^https?://[^/]+", BASE, url)
jeton = eleve.post(url, headers={"X-CSRF-TOKEN": csrf}).json()["jeton"]
consoles[nom] = websocket.create_connection(f"{BASE_WS}/console/{jeton}", timeout=10)
# Comme le navigateur : les jetons des consoles sont demandés en parallèle
# (une série de fetch sans attente). Les demander l'un après l'autre
# ajoutait ~2 s à la mesure (décomposition : decomposer-ouverture.py).
noms = re.findall(r'data-onglet="\d+"[^>]*>([^<]+)<', page)
urls = [re.sub(r"^https?://[^/]+", BASE, u) for u in re.findall(r"fetch\('(http[^']+/console)'", page)]
with ThreadPoolExecutor(len(urls)) as pool:
jetons = list(pool.map(lambda u: eleve.post(u, headers={"X-CSRF-TOKEN": csrf}).json()["jeton"], urls))
consoles = {nom: websocket.create_connection(f"{BASE_WS}/console/{j}", timeout=10) for nom, j in zip(noms, jetons)}
def lire_jusqua(ws, motif, delai=15):