Server : Apache System : Linux webd348.cluster026.gra.hosting.ovh.net 5.15.148-ovh-vps-grsec-zfs-classid #1 SMP Thu Feb 8 09:41:04 UTC 2024 x86_64 User : hednacluml ( 122243) PHP Version : 8.3.9 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl Directory : /home/hednacluml/liberlog/ecrire/inc/ |
<?php /***************************************************************************\ * SPIP, Système de publication pour l'internet * * * * Copyright © avec tendresse depuis 2001 * * Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribué sous licence GNU/GPL. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) { return; } /** * Gestion des tâches de fond * * Deux difficultés : * - la plupart des hebergeurs ne fournissent pas le Cron d'Unix * - les scripts usuels standard sont limites à 30 secondes * * Solution * -------- * Toute connexion à SPIP s'achève par un appel (asynchrone si possible) * à la fonction `cron()` qui appelle la fonction surchargeable `inc_genie_dist()` * * Sa définition standard ci-dessous prend dans une liste de tâches * la plus prioritaire. * * Une fonction exécutant une tâche doit retourner un nombre : * - nul, si la tache n'a pas à être effecutée * - positif, si la tache a été effectuée * - négatif, si la tache doit être poursuivie ou recommencée * * Elle recoit en argument la date de la dernière exécution de la tâche. * * On peut appeler cette fonction avec d'autres tâches (pour étendre SPIP) * spécifiée par des fonctions respectant le protocole ci-dessus. * * On peut ajouter des tâches périodiques ou modifier la fréquence * de chaque tâche et leur priorité en utilisant le pipeline * `taches_generales_cron`. * * On peut également directement en déclarer avec la balise `genie` d'un paquet.xml * de plugin, tel que `<genie nom="nom_de_la_tache" periode="86400" />` * * @package SPIP\Core\Genie **/ /** * Prévoit l'exécution de la tâche cron la plus urgente * * Les tâches sont dans un tableau `'nom de la tâche' => périodicité` * * Cette fonction exécute la tache la plus urgente, c'est à dire * celle dont la date de dernière exécution + la périodicité est minimale. * * La date de la prochaîne exécution de chaque tâche est indiquée dans la * table SQL `spip_jobs` * * La fonction exécutant la tâche est (généralement) un homonyme de préfixe "genie_". * Le fichier homonyme du repertoire "genie/" est automatiquement lu * et il est supposé définir cette fonction. * * @uses queue_add_job() Lorsqu'une tâche est à forcer * @uses queue_schedule() * @see taches_generales() Liste des tâches déclarées * * @param array $taches * Tâches dont on force maintenant l'exécution le plus tôt possible. * Sinon, prendra la tâche la plus prioritaire. * @return **/ function inc_genie_dist($taches = []) { include_spip('inc/queue'); if (_request('exec') == 'job_queue') { return false; } $force_jobs = []; // l'ancienne facon de lancer une tache cron immediatement // etait de la passer en parametre a ing_genie_dist // on reroute en ajoutant simplement le job a la queue, ASAP foreach ($taches as $function => $period) { $force_jobs[] = queue_add_job( $function, _T('tache_cron_asap', ['function' => $function]), [time() - abs($period)], 'genie/' ); } // et on passe la main a la gestion de la queue ! // en forcant eventuellement les jobs ajoute a l'instant return queue_schedule(count($force_jobs) ? $force_jobs : null); } // // Construction de la liste des taches. // la cle est la tache, // la valeur le temps minimal, en secondes, entre deux memes taches // NE PAS METTRE UNE VALEUR INFERIEURE A 30 // les serveurs Http n'accordant en general pas plus de 30 secondes // a leur sous-processus // function taches_generales($taches_generales = []) { // verifier que toutes les taches cron sont planifiees // c'est une tache cron ! $taches_generales['queue_watch'] = 3600 * 24; // MAJ des rubriques publiques (cas de la publication post-datee) // est fait au coup par coup a present // $taches_generales['rubriques'] = 3600; // Optimisation de la base $taches_generales['optimiser'] = 3600 * 48; // nouveautes if ( isset($GLOBALS['meta']['adresse_neuf']) && $GLOBALS['meta']['adresse_neuf'] && (int) $GLOBALS['meta']['jours_neuf'] && $GLOBALS['meta']['quoi_de_neuf'] == 'oui' ) { $taches_generales['mail'] = 3600 * 24 * (int) $GLOBALS['meta']['jours_neuf']; } // maintenance (ajax, verifications diverses) $taches_generales['maintenance'] = 3600 * 2; // verifier si une mise a jour de spip est disponible (2 fois par semaine suffit largement) $taches_generales['mise_a_jour'] = 3 * 24 * 3600; return pipeline('taches_generales_cron', $taches_generales); } /** * Une tâche périodique pour surveiller les tâches crons et les relancer si besoin * * Quand ce cron s'execute, il n'est plus dans la queue, donc il se replanifie * lui même, avec last=time() * avec une dose d'aleatoire pour ne pas planifier toutes les taches au meme moment * * @uses taches_generales() * @uses queue_genie_replan_job() * * @return int */ function genie_queue_watch_dist() { static $deja_la = false; if ($deja_la) { return; } // re-entrance si l'insertion des jobs echoue (pas de table spip_jobs a l'upgrade par exemple) $deja_la = true; $taches = taches_generales(); $programmees = sql_allfetsel('fonction', 'spip_jobs', sql_in('fonction', array_keys($taches))); $programmees = array_column($programmees, 'fonction'); foreach ($taches as $tache => $periode) { if (!in_array($tache, $programmees)) { queue_genie_replan_job($tache, $periode, time() - round(random_int(1, $periode)), 0); } } $deja_la = false; return 1; } /** * Replanifier une tache periodique * * @param string $function * nom de la fonction a appeler * @param int $period * periodicite en secondes * @param int $last * date du dernier appel (timestamp) * @param int $time * date de replanification * si null calculee automaitquement a partir de $last et $period * si 0 = asap mais on n'insere pas le job si deja en cours d'execution * @param int $priority * priorite * @return void */ function queue_genie_replan_job($function, $period, $last = 0, $time = null, $priority = 0) { static $done = []; if (isset($done[$function])) { return; } $done[$function] = true; if (is_null($time)) { $time = time(); if ($last) { $time = max($last + $period, $time); } } if (!$last) { $last = $time - $period; } spip_log("replan_job $function $period $last $time $priority", 'queue'); include_spip('inc/queue'); // on replanifie un job cron // uniquement si il n'y en a pas deja un avec le meme nom // independament de l'argument queue_add_job( $function, _T('tache_cron_secondes', ['function' => $function, 'nb' => $period]), [$last], 'genie/', 'function_only', $time, $priority ); }