|
|
|
@ -100,22 +100,38 @@ function cachelab_prepare_conditions($conditions) {
|
|
|
|
|
$cle_objet=null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$plus_args=[]; |
|
|
|
|
// pour 'contexte' on simule un 'plus' pour donner un exemple d'extension |
|
|
|
|
if (isset($conditions['contexte']) and $conditions['contexte'] and !isset($conditions['plus'])) { |
|
|
|
|
$conditions['plus'] = 'contexte'; |
|
|
|
|
$plus_args = $conditions['contexte']; |
|
|
|
|
} |
|
|
|
|
if ($plus = (isset($conditions['plus']) ? (string)$conditions['plus'] : '')) { |
|
|
|
|
|
|
|
|
|
$plus = (isset($conditions['plus']) ? (string)$conditions['plus'] : ''); |
|
|
|
|
if ($plus) { |
|
|
|
|
$plusfunc='cachelab_ciblercache_'.$plus; |
|
|
|
|
// Signature nécessaire : $plusfunc ($action, $conditions, $options, &$stats) |
|
|
|
|
if (!function_exists($plusfunc)) { |
|
|
|
|
spip_log("La fonction '$plusfunc' n'est pas définie", 'cachelab_erreur'); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
if(!$plus_args and isset($conditions['plus_args'])) { |
|
|
|
|
$plus_args = $conditions['plus_args']; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
$plusfunc = ''; |
|
|
|
|
} |
|
|
|
|
return array ($session, $chemin, $chemins, $cle_objet, $id_objet, $plusfunc); |
|
|
|
|
return [ |
|
|
|
|
'session' => $session, |
|
|
|
|
'chemin' => $chemin, |
|
|
|
|
'chemins' => $chemins, |
|
|
|
|
'cle_objet' => $cle_objet, |
|
|
|
|
'id_objet' => $id_objet, |
|
|
|
|
'plusfunc' => $plusfunc, |
|
|
|
|
'plus_args' => $plus_args |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
* Applique une action donnée à tous les caches vérifiant certaines conditions |
|
|
|
@ -141,8 +157,7 @@ global $Memoization;
|
|
|
|
|
|
|
|
|
|
// Prise en compte des OU (alternatives de conditions) |
|
|
|
|
// Attention la réentrance n'est pas prévue historiquement alors surprises en perspectives |
|
|
|
|
$l_conditions = (isset($conditions['ou']) ? $conditions['ou'] : '') |
|
|
|
|
or (isset($conditions['or']) ? $conditions['or'] : ''); |
|
|
|
|
$l_conditions = (isset($conditions['ou']) ? $conditions['ou'] : '') or (isset($conditions['or']) ? $conditions['or'] : ''); |
|
|
|
|
if (!$l_conditions) { |
|
|
|
|
$l_conditions = array($conditions); |
|
|
|
|
} |
|
|
|
@ -150,13 +165,17 @@ global $Memoization;
|
|
|
|
|
spip_log ("La condition OU ou OR pour cachelab_cibler($action,...) n'est pas un tableau : " . print_r ($conditions, 1), 'cachelab_erreur'); |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
debug_log("OU liste operandes = ".print_r($l_conditions,1), "DEBUG_cachelab_ou"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// $l_conditions est un tableau de conditions élémentaires |
|
|
|
|
// La condition globale est statisfaite si l'une des condition est satisfaite (OR) |
|
|
|
|
// Chaque condition élémentaire est satisfaite si chacune de ses composantes est satisfaite |
|
|
|
|
// La condition globale est satisfaite si l'une des condition est satisfaite (OR) |
|
|
|
|
// Chaque condition élémentaire est satisfaite si chacune de ses composantes est satisfaite (AND) |
|
|
|
|
|
|
|
|
|
$l_conditions = array_map ('cachelab_prepare_conditions', $l_conditions); |
|
|
|
|
// prend la forme d'un tableau de conditions précalculées [$session, $chemin, $chemins, $cle_objet, $id_objet, $plusfunc] |
|
|
|
|
if (_request('exec')=='xray' and _request('debug')=='cachelab') echo "<h3>Les conditions préparées</h3><xmp>".print_r($l_conditions,1)."</xmp>"; |
|
|
|
|
|
|
|
|
|
// options |
|
|
|
|
// explode+strpos par défaut pour les chemins |
|
|
|
@ -179,50 +198,62 @@ global $Memoization;
|
|
|
|
|
$meta_derniere_modif = $GLOBALS['meta']['derniere_modif']; |
|
|
|
|
$len_prefix = strlen(_CACHE_NAMESPACE); |
|
|
|
|
|
|
|
|
|
$n_cache = 0; |
|
|
|
|
foreach ($cache['cache_list'] as $d) { |
|
|
|
|
$n_cache++; |
|
|
|
|
// on "continue=passe au suivant" dés qu'on sait que le cache n'est pas cible |
|
|
|
|
$cle = $d['info']; |
|
|
|
|
$data=null; |
|
|
|
|
|
|
|
|
|
// on passe les caches non concernés |
|
|
|
|
if (true) { |
|
|
|
|
// on saute les caches d'autres origines |
|
|
|
|
// (et les caches d'un autre _CACHE_NAMESPACE pour ce même site) |
|
|
|
|
if (strpos($cle, _CACHE_NAMESPACE) !== 0) { |
|
|
|
|
$stats['nb_alien']++; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
// on passe les caches non concernés car d'autres origines |
|
|
|
|
// (et les caches d'un autre _CACHE_NAMESPACE pour ce même site) |
|
|
|
|
if (strpos($cle, _CACHE_NAMESPACE) !== 0) { |
|
|
|
|
$stats['nb_alien']++; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// on ne veut examiner que les caches de squelettes SPIP |
|
|
|
|
if (substr($cle, $len_prefix-1, 7) != ':cache:') { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
// on ne veut examiner que les caches de squelettes SPIP |
|
|
|
|
if (substr($cle, $len_prefix-1, 7) != ':cache:') { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// effacer ou sauter les caches invalidés par une invalidation totale |
|
|
|
|
// ou que apcu ne suit plus |
|
|
|
|
if ($meta_derniere_modif > $d['creation_time'] |
|
|
|
|
or !apcu_exists($cle)) { |
|
|
|
|
if ($do_clean) { |
|
|
|
|
$memoiz_cle=substr($cle, $len_prefix); |
|
|
|
|
// Avant ce test il arrivait parfois des salves de 10 à 50 logs d'échec du clean cache simultanés (mm t, mm pid) |
|
|
|
|
if ($Memoization->exists($memoiz_cle)) { |
|
|
|
|
$del = $Memoization->del($memoiz_cle); |
|
|
|
|
if (!$del) { |
|
|
|
|
spip_log("Echec de Memoization->del du cache $cle (création : {$d['creation_time']}, invalidation : $meta_derniere_modif)", 'cachelab_ERREUR'); |
|
|
|
|
} |
|
|
|
|
$stats['nb_clean']++; |
|
|
|
|
// effacer ou sauter les caches invalidés par une invalidation totale |
|
|
|
|
// ou que apcu ne suit plus |
|
|
|
|
if ($meta_derniere_modif > $d['creation_time'] |
|
|
|
|
or !apcu_exists($cle)) { |
|
|
|
|
if ($do_clean) { |
|
|
|
|
$memoiz_cle=substr($cle, $len_prefix); |
|
|
|
|
// Avant ce test il arrivait parfois des salves de 10 à 50 logs d'échec du clean cache simultanés (mm t, mm pid) |
|
|
|
|
if ($Memoization->exists($memoiz_cle)) { |
|
|
|
|
$del = $Memoization->del($memoiz_cle); |
|
|
|
|
if (!$del) { |
|
|
|
|
spip_log("Echec de Memoization->del du cache $cle (création : {$d['creation_time']}, invalidation : $meta_derniere_modif)", 'cachelab_ERREUR'); |
|
|
|
|
} |
|
|
|
|
$stats['nb_clean']++; |
|
|
|
|
} |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// caches SPIP véritablement candidats |
|
|
|
|
// Il reste les caches SPIP véritablement candidats |
|
|
|
|
$stats['nb_candidats']++; |
|
|
|
|
|
|
|
|
|
$n_condition=0; |
|
|
|
|
$cible = false; |
|
|
|
|
// La premiere condition élémentaire composée entièrement satisfaite |
|
|
|
|
foreach ($l_conditions as list ($session, $chemin, $chemins, $cle_objet, $id_objet, $plusfunc)) { |
|
|
|
|
foreach ($l_conditions as $i_conditions) { |
|
|
|
|
$n_condition++; |
|
|
|
|
$session = $i_conditions['session']; |
|
|
|
|
$chemin = $i_conditions['chemin']; |
|
|
|
|
$chemins = $i_conditions['chemins']; |
|
|
|
|
$cle_objet = $i_conditions['cle_objet']; |
|
|
|
|
$id_objet = $i_conditions['id_objet']; |
|
|
|
|
$plusfunc = $i_conditions['plusfunc']; |
|
|
|
|
// $plus_args = $plusfunc['plus_args']; utilisé seulement dans la plusfunc |
|
|
|
|
|
|
|
|
|
if (($n_cache==1) and (_request('exec')=='xray') and (_request('debug')=='cachelab')) { |
|
|
|
|
echo "<b>Condition $n_condition</b> : chemin=$chemin, plusfunc=$plusfunc<br><xmp>".print_r($i_conditions,1)."</xmp>"; |
|
|
|
|
} |
|
|
|
|
// 1er filtrage : par la session |
|
|
|
|
if ($session) { |
|
|
|
|
if (substr ($cle, -9) != "_$session") { |
|
|
|
@ -299,7 +330,7 @@ global $Memoization;
|
|
|
|
|
|
|
|
|
|
// 4eme filtre : par une extension |
|
|
|
|
if ($plusfunc |
|
|
|
|
and !$plusfunc($action, $conditions, $options, $cle, $data, $stats)) { |
|
|
|
|
and !$plusfunc($action, $i_conditions, $options, $cle, $data, $stats)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -317,6 +348,10 @@ global $Memoization;
|
|
|
|
|
$stats['l_cible'][] = $cle; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (_request('exec')=='xray' and _request('debug')=='cachelab') { |
|
|
|
|
echo "Avec condition $n_condition trouvé $cle, nb_cible devient ".$stats['nb_cible']."<br>"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cachelab_appliquer($action, $cle, $data, $options, $return); |
|
|
|
|
|
|
|
|
|
if ($return |
|
|
|
@ -397,11 +432,19 @@ static $prev_derniere_modif_invalide;
|
|
|
|
|
* @return bool |
|
|
|
|
*/ |
|
|
|
|
function cachelab_ciblercache_contexte($action, $conditions, $options, $cle, &$data, &$stats) { |
|
|
|
|
if (!isset($data['contexte']) |
|
|
|
|
or !isset($conditions['contexte']) |
|
|
|
|
or !is_array($conditions['contexte'])) { |
|
|
|
|
if (!isset($data['contexte'])) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
$diff = array_diff_assoc($conditions['contexte'], $data['contexte']); |
|
|
|
|
if (!isset($conditions['plus_args']) or !is_array($conditions['plus_args'])) { |
|
|
|
|
// debug_assert(false, "cachelab_ciblercache_contexte sans contexte dans plus_args($action, conditions=".print_r($conditions,1)); |
|
|
|
|
// la phpstack fait planter donc pas d'assert |
|
|
|
|
$m = "cachelab_ciblercache_contexte sans contexte dans plus_args ($action, conditions=<xmp>".print_r($conditions,1)."</xmp>"; |
|
|
|
|
echo "ERREUR $m"; |
|
|
|
|
spip_log($m, "ERREUR_cachelab_contexte"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
$diff = array_diff_assoc($conditions['plus_args'], $data['contexte']); |
|
|
|
|
return empty($diff); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|