#!/usr/bin/env python3 """Décompose le temps d'ouverture d'un lab déjà admis (étape 13) : où passent les secondes entre « la page voit l'état actif » et « l'invite login: » ? Usage (sur le serveur, séance préparée par preparer-parcours.php et élève déjà admis par parcours-lab.py) : sudo -u www-data python3 tests/Reels/decomposer-ouverture.py """ import json import os import re import time from concurrent.futures import ThreadPoolExecutor import requests import websocket BASE = os.environ.get("PARCOURS_BASE", "https://syllabuslab.fr") BASE_WS = re.sub(r"^http", "ws", BASE) ids = json.load(open("/tmp/parcours-identifiants.json")) s = requests.Session() tok = re.search(r'name="_token" value="([^"]+)"', s.get(BASE + "/connexion").text).group(1) s.post(BASE + "/connexion/eleve", data={"_token": tok, "identifiant": ids["eleve_identifiant"], "code": ids["eleve_code"]}) def chrono(f): t = time.time() r = f() return r, time.time() - t def jeton(url, csrf): return s.post(url, headers={"X-CSRF-TOKEN": csrf}).json()["jeton"] def invite(jeton_console): ws = websocket.create_connection(f"{BASE_WS}/console/{jeton_console}", timeout=10) ws.send("\r") sortie, fin = b"", time.time() + 10 # « login: » sur une VM neuve, « $ » si quelqu'un y est déjà connecté. while not re.search(rb"login:|\$ ", sortie) and time.time() < fin: m = ws.recv() sortie += m if isinstance(m, bytes) else m.encode() ws.close() for essai in range(1, 4): (page, t_page) = chrono(lambda: s.get(f"{BASE}/seances/{ids['seance_id']}/attente-eleve").text) csrf = re.search(r"'X-CSRF-TOKEN': '([^']+)'", page).group(1) urls = [re.sub(r"^https?://[^/]+", BASE, u) for u in re.findall(r"fetch\('(http[^']+/console)'", page)] (jetons_seq, t_seq) = chrono(lambda: [jeton(u, csrf) for u in urls]) with ThreadPoolExecutor(len(urls)) as pool: (jetons_par, t_par) = chrono(lambda: list(pool.map(lambda u: jeton(u, csrf), urls))) (_, t_ws) = chrono(lambda: invite(jetons_par[0])) navigateur = 1.0 + t_page + t_par + t_ws print(f"essai {essai} : page {t_page:.2f} s | 3 jetons console : séquentiel {t_seq:.2f} s, parallèle {t_par:.2f} s " f"| WebSocket → login: {t_ws:.2f} s | chemin navigateur (pire attente d'interrogation 1 s) ≈ {navigateur:.2f} s")