- BDD (migrations 1.6.0 + 1.7.0, idempotentes) :
* 4 nouveaux index composites sur reactevents, triggerevents, sessions
* vue sessiondebriefs reecrite (sous-requetes correlees -> JOINs)
puis materialisee dans table session_debriefs_cache via procedure
stockee rebuild_debrief_cache, recalculee uniquement aux changements
* fix bug double JOIN participates : TargetRole = "IA" pour les hits
NPC/objets (au lieu d'un role aleatoire de participant)
- API PHP :
* connexion PDO en singleton + ATTR_PERSISTENT
* cache disque par session (cache/sess_<id>/) pour debrief, get, userhistory
avec invalidation ciblee sur events et lifecycle
* pagination opt-in (limit/offset) sur lists/sessions_for_user
* helpers ensure_/rebuild_/invalidate_session_debrief_cache_db
* debug/benchmark.php pour mesurer la latence des 6 endpoints cles
- Endpoints HTTP : signatures inchangees, compat Unreal preservee
- Gain mesure : -58% a -83% sur les 5 endpoints cles
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
107 lines
4.1 KiB
PHP
107 lines
4.1 KiB
PHP
<?php
|
|
// Mesure de latence des endpoints lourds de l'API ProserveAPI.
|
|
// A lancer AVANT et APRES chaque palier d'optimisation pour avoir des chiffres comparatifs.
|
|
// Usage : POST sur ce fichier avec optionnellement userId et sessionId.
|
|
// curl -X POST -d "userId=1&sessionId=42" http://localhost/proserve/debug/benchmark.php
|
|
// ou ouvrir directement dans le navigateur (lance avec userId=-1 et sessionId=-1, certains endpoints retourneront vide mais la mesure du round-trip reste valide).
|
|
|
|
include_once '../config/init.php';
|
|
|
|
$userId = isset($_POST['userId']) ? intval($_POST['userId']) : (isset($_GET['userId']) ? intval($_GET['userId']) : -1);
|
|
$sessionId = isset($_POST['sessionId']) ? intval($_POST['sessionId']) : (isset($_GET['sessionId']) ? intval($_GET['sessionId']) : -1);
|
|
$iterations = isset($_POST['iterations']) ? max(1, intval($_POST['iterations'])) : (isset($_GET['iterations']) ? max(1, intval($_GET['iterations'])) : 5);
|
|
|
|
// si pas de sessionId fourni, prendre la plus recente pour avoir des donnees realistes
|
|
if ($sessionId <= 0) {
|
|
$stmt = $db->query("SELECT id FROM sessions ORDER BY id DESC LIMIT 1");
|
|
$row = $stmt ? $stmt->fetch(PDO::FETCH_ASSOC) : null;
|
|
if ($row) $sessionId = intval($row['id']);
|
|
}
|
|
if ($userId <= 0) {
|
|
$stmt = $db->query("SELECT userId FROM participates WHERE sessionId=" . intval($sessionId) . " LIMIT 1");
|
|
$row = $stmt ? $stmt->fetch(PDO::FETCH_ASSOC) : null;
|
|
if ($row) $userId = intval($row['userId']);
|
|
}
|
|
|
|
// resolution de l'URL de base (meme host et meme path)
|
|
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
|
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
|
$base = $scheme . '://' . $host . rtrim(dirname(dirname($_SERVER['SCRIPT_NAME'])), '/\\');
|
|
|
|
$endpoints = [
|
|
'session/debrief' => ['sessionId' => $sessionId, 'userId' => $userId],
|
|
'session/get' => ['sessionId' => $sessionId],
|
|
'stats/userhistory' => ['userId' => $userId, 'sessionId' => $sessionId, 'quickMode' => 'false'],
|
|
'stats/get' => ['userId' => $userId, 'sessionId' => $sessionId],
|
|
'lists/sessions_for_user' => ['userId' => $userId],
|
|
'lists/users_in_session' => ['sessionId' => $sessionId],
|
|
];
|
|
|
|
function call_endpoint($url, $params)
|
|
{
|
|
// ext-curl est dispo dans XAMPP par defaut et bcp plus rapide que
|
|
// file_get_contents+stream_context_create sur Windows (qui ajoute ~10ms par appel).
|
|
static $ch = null;
|
|
if ($ch === null) {
|
|
$ch = curl_init();
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_POST => true,
|
|
CURLOPT_TIMEOUT => 60,
|
|
CURLOPT_FORBID_REUSE => false,
|
|
CURLOPT_FRESH_CONNECT => false,
|
|
]);
|
|
}
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
|
|
|
|
$start = microtime(true);
|
|
$resp = curl_exec($ch);
|
|
$elapsed_ms = (microtime(true) - $start) * 1000;
|
|
$err = curl_errno($ch);
|
|
|
|
return [
|
|
'ms' => round($elapsed_ms, 2),
|
|
'bytes' => $resp === false ? 0 : strlen($resp),
|
|
'ok' => $err === 0 && $resp !== false,
|
|
];
|
|
}
|
|
|
|
function summarize($samples)
|
|
{
|
|
$times = array_column($samples, 'ms');
|
|
sort($times);
|
|
$n = count($times);
|
|
return [
|
|
'min' => $times[0],
|
|
'max' => $times[$n - 1],
|
|
'median' => $times[intval($n / 2)],
|
|
'avg' => round(array_sum($times) / $n, 2),
|
|
'bytes' => $samples[0]['bytes'],
|
|
'ok' => count(array_filter(array_column($samples, 'ok'))) === $n,
|
|
];
|
|
}
|
|
|
|
$results = [
|
|
'context' => [
|
|
'userId' => $userId,
|
|
'sessionId' => $sessionId,
|
|
'iterations' => $iterations,
|
|
'base_url' => $base,
|
|
'timestamp' => date('c'),
|
|
],
|
|
'endpoints' => [],
|
|
];
|
|
|
|
foreach ($endpoints as $path => $params) {
|
|
$url = $base . '/' . $path . '.php';
|
|
$samples = [];
|
|
for ($i = 0; $i < $iterations; $i++) {
|
|
$samples[] = call_endpoint($url, $params);
|
|
}
|
|
$results['endpoints'][$path] = summarize($samples);
|
|
}
|
|
|
|
print_r(json_encode($results, JSON_PRETTY_PRINT));
|
|
?>
|