V2 : optimisation API (cache, index, vue materialisee)
- 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>
This commit is contained in:
@@ -118,7 +118,8 @@ class StatsObject extends DBTableObject
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get sessions of given type that given user has taken part in
|
||||
public function getRawSessions ($userId=-1, $typeId=-1)
|
||||
// $limit and $offset are optional : when $limit <= 0 the full list is returned (legacy behavior)
|
||||
public function getRawSessions ($userId=-1, $typeId=-1, $limit=-1, $offset=0)
|
||||
{
|
||||
// Check if we are looking for a specific user and/or type of session
|
||||
$userConstraint = $userId > 0 ? " AND P.userId=" . $userId : "";
|
||||
@@ -126,11 +127,17 @@ class StatsObject extends DBTableObject
|
||||
|
||||
// Order results from newest to oldest session
|
||||
$orderConstraint = " ORDER BY SD.id DESC";
|
||||
|
||||
//$query = "SELECT DISTINCT S.* FROM " . SESSIONS_TABLE_NAME . " S LEFT JOIN " . PARTICIPATES_TABLE_NAME . " P ON S.id = P.sessionId WHERE 1 " .
|
||||
|
||||
// Optional pagination : SQL-level LIMIT/OFFSET when caller provided a positive limit
|
||||
$limitConstraint = "";
|
||||
if (intval($limit) > 0) {
|
||||
$limitConstraint = " LIMIT " . intval($limit) . " OFFSET " . max(0, intval($offset));
|
||||
}
|
||||
|
||||
//$query = "SELECT DISTINCT S.* FROM " . SESSIONS_TABLE_NAME . " S LEFT JOIN " . PARTICIPATES_TABLE_NAME . " P ON S.id = P.sessionId WHERE 1 " .
|
||||
$query = "SELECT DISTINCT SD.* FROM " . SESSIONS_TABLE_NAME . " SD, " . PARTICIPATES_TABLE_NAME . " P WHERE SD.id = P.sessionId " .
|
||||
$this->getCalibrationSessionsConstraint("SD") . $this->getSessionDurationConstraint("SD") . $userConstraint . $typeConstraint . $orderConstraint;
|
||||
|
||||
$this->getCalibrationSessionsConstraint("SD") . $this->getSessionDurationConstraint("SD") . $userConstraint . $typeConstraint . $orderConstraint . $limitConstraint;
|
||||
|
||||
// prepare and execute query
|
||||
$stmt = $this->conn->prepare($query);
|
||||
$stmt->execute();
|
||||
@@ -141,11 +148,11 @@ class StatsObject extends DBTableObject
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// get sessions that given user has taken part in
|
||||
public function getSessionsForUser ($userId, $typeId=-1)
|
||||
public function getSessionsForUser ($userId, $typeId=-1, $limit=-1, $offset=0)
|
||||
{
|
||||
// Check if we are looking for a specific user and/or session
|
||||
$stmt = $this->getRawSessions($userId, $typeId);
|
||||
|
||||
$stmt = $this->getRawSessions($userId, $typeId, $limit, $offset);
|
||||
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
|
||||
{
|
||||
//$sess = new GameSession($this->conn);
|
||||
@@ -469,11 +476,16 @@ class StatsObject extends DBTableObject
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lazy rebuild du cache materialise pour cette session avant le SELECT FROM sessiondebriefs
|
||||
if ($sessionId > 0 && function_exists('ensure_session_debriefs_cached_db')) {
|
||||
ensure_session_debriefs_cached_db($this->conn, $sessionId);
|
||||
}
|
||||
|
||||
// create SQL constraints for query
|
||||
$sessionConstraint = $sessionId > 0 ? " AND SD.SessionId = " . $sessionId : "";
|
||||
$userConstraint = $userId >= 0 ? " AND SD.ShooterId = " . $userId : "";
|
||||
$userSubConstraint = $userId >= 0 ? " AND P.UserId = " . $userId : "";
|
||||
|
||||
|
||||
// get raw results from query
|
||||
$sessionStats = $this->getRawStatsForSession ($sessionId, $userId, -1);
|
||||
|
||||
@@ -692,9 +704,15 @@ class StatsObject extends DBTableObject
|
||||
// debrief mission : get given users results in given session
|
||||
public function getResultsForSession ($sessionId, $userId, $fromUserId=-1)
|
||||
{
|
||||
// Lazy rebuild du cache materialise (table session_debriefs_cache)
|
||||
// si la session a ete invalidee par un evenement et pas encore reconstruite
|
||||
if ($sessionId > 0 && function_exists('ensure_session_debriefs_cached_db')) {
|
||||
ensure_session_debriefs_cached_db($this->conn, $sessionId);
|
||||
}
|
||||
|
||||
$userConstraint = $userId > 0 ? " AND SD.ShooterId=" . $userId : "";
|
||||
$sessionConstraint = $sessionId > 0 ? " AND SD.SessionId=" . $sessionId : "";
|
||||
|
||||
|
||||
$query = "SELECT SD.* FROM " . SESSIONDEBRIEFS_VIEW_NAME . " SD WHERE 1 " . $this->getCalibrationSessionsConstraint() . $userConstraint . $sessionConstraint . " GROUP BY SD.SessionId, SD.ShooterId, SD.ShotIndex";
|
||||
//$query = "SELECT SD.* FROM (" . SESSIONDEBRIEFS_VIEW_QUERY . ") AS SD WHERE 1 " . $userConstraint . $sessionConstraint . " GROUP BY SD.SessionId, SD.ShooterId, SD.ShotIndex";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user