perf: cache locking, TTL map, purge script and SW LRU limit
This commit is contained in:
+74
-28
@@ -6,11 +6,11 @@
|
||||
class SimpleAPICache {
|
||||
private $cacheDir;
|
||||
private $enabled;
|
||||
|
||||
public function __construct() {
|
||||
$this->cacheDir = __DIR__ . '/../cache/api';
|
||||
|
||||
public function __construct($cacheDir = null) {
|
||||
$this->cacheDir = $cacheDir ?? (__DIR__ . '/../cache/api');
|
||||
$this->enabled = true;
|
||||
|
||||
|
||||
// Créer le répertoire de cache s'il n'existe pas
|
||||
if (!is_dir($this->cacheDir)) {
|
||||
mkdir($this->cacheDir, 0755, true);
|
||||
@@ -66,9 +66,28 @@ class SimpleAPICache {
|
||||
'created' => time()
|
||||
];
|
||||
|
||||
file_put_contents($file, json_encode($data));
|
||||
// Verrou exclusif : évite les écritures concurrentes tronquées
|
||||
file_put_contents($file, json_encode($data), LOCK_EX);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Vide entièrement le cache (entrées valides comme expirées)
|
||||
*
|
||||
* @return int Nombre de fichiers supprimés
|
||||
*/
|
||||
public function clear() {
|
||||
$files = glob($this->cacheDir . '/cache_*.json');
|
||||
$deleted = 0;
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (unlink($file)) {
|
||||
$deleted++;
|
||||
}
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nettoie le cache expiré
|
||||
*/
|
||||
@@ -91,44 +110,71 @@ class SimpleAPICache {
|
||||
// Instance globale
|
||||
$GLOBALS['simple_api_cache'] = new SimpleAPICache();
|
||||
|
||||
/**
|
||||
* TTL de cache selon l'endpoint PeerTube.
|
||||
*
|
||||
* Correspondance exacte d'abord, puis par préfixe. L'ancien matching par
|
||||
* sous-chaîne (strpos) créait des collisions : « accounts/{nom}/videos »
|
||||
* capturait le TTL de « videos » (10 min) au lieu de celui de « accounts »
|
||||
* (5 min, pensé pour les lives).
|
||||
*
|
||||
* @param string $endpoint Endpoint de l'API (sans slash initial)
|
||||
* @return int TTL en secondes
|
||||
*/
|
||||
function getPeerTubeCacheTtl($endpoint) {
|
||||
static $exactMap = [
|
||||
'videos/categories' => 3600, // 1 heure
|
||||
'videos' => 600, // 10 minutes
|
||||
'search/videos' => 600, // 10 minutes
|
||||
'wp-posts' => 900, // 15 minutes pour WordPress
|
||||
'accounts' => 300 // 5 minutes pour live streams
|
||||
];
|
||||
|
||||
static $prefixMap = [
|
||||
'accounts/' => 300, // lives : accounts/{nom}/videos
|
||||
'video-channels/' => 600, // vidéos d'une chaîne
|
||||
'videos/' => 600 // videos/{id}, commentaires
|
||||
];
|
||||
|
||||
if (isset($exactMap[$endpoint])) {
|
||||
return $exactMap[$endpoint];
|
||||
}
|
||||
|
||||
foreach ($prefixMap as $prefix => $ttl) {
|
||||
if (strpos($endpoint, $prefix) === 0) {
|
||||
return $ttl;
|
||||
}
|
||||
}
|
||||
|
||||
return 300; // Défaut 5 minutes
|
||||
}
|
||||
|
||||
/**
|
||||
* Version cachée de callPeerTubeApi - remplace l'originale
|
||||
*/
|
||||
function callPeerTubeApiCached($endpoint, $params = []) {
|
||||
$cache = $GLOBALS['simple_api_cache'];
|
||||
|
||||
// TTL selon le type de contenu
|
||||
$ttlMap = [
|
||||
'videos/categories' => 3600, // 1 heure
|
||||
'videos' => 600, // 10 minutes (augmenté)
|
||||
'search/videos' => 600, // 10 minutes
|
||||
'wp-posts' => 900, // 15 minutes pour WordPress
|
||||
'accounts' => 300 // 5 minutes pour live streams
|
||||
];
|
||||
|
||||
// TTL dynamique selon l'endpoint
|
||||
$ttl = 300; // Défaut 5 minutes
|
||||
foreach ($ttlMap as $pattern => $time) {
|
||||
if (strpos($endpoint, $pattern) !== false) {
|
||||
$ttl = $time;
|
||||
break;
|
||||
}
|
||||
// Cache désactivé : appel direct, sans lecture ni écriture
|
||||
if (!defined('CACHE_ENABLED') || !CACHE_ENABLED) {
|
||||
return callPeerTubeApiOriginal($endpoint, $params);
|
||||
}
|
||||
|
||||
|
||||
$cache = $GLOBALS['simple_api_cache'];
|
||||
$ttl = getPeerTubeCacheTtl($endpoint);
|
||||
|
||||
// Essayer le cache d'abord
|
||||
$cached = $cache->get($endpoint, $params);
|
||||
if ($cached !== null) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
|
||||
// Appeler l'API originale
|
||||
$data = callPeerTubeApiOriginal($endpoint, $params);
|
||||
|
||||
|
||||
// Mettre en cache si on a des données
|
||||
if (!empty($data)) {
|
||||
$cache->set($endpoint, $params, $data, $ttl);
|
||||
}
|
||||
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user