[SPIP] ~maj v3.0.14-->v3.0.17
[ptitvelo/web/www.git] / www / ecrire / inc / genie.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 // --------------------------
16 // Gestion des taches de fond
17 // --------------------------
18
19 // Deux difficultes:
20 // - la plupart des hebergeurs ne fournissent pas le Cron d'Unix
21 // - les scripts usuels standard sont limites a 30 secondes
22
23 // Solution:
24 // Toute connexion a SPIP s'acheve par un appel a la fonction cron()
25 // qui appelle la fonction surchargeable genie dans inc/
26 // Sa definition standard ci-dessous prend dans une liste de taches
27 // la plus prioritaire, leurs dates etant donnees par leur fichier-verrou.
28 // Une fonction executant une tache doit retourner un nombre:
29 // - nul, si la tache n'a pas a etre effecutee
30 // - positif, si la tache a ete effectuee
31 // - negatif, si la tache doit etre poursuivie ou recommencee
32 // Elle recoit en argument la date de la derniere execution de la tache.
33
34 // On peut appeler cette fonction avec d'autres taches (pour etendre Spip)
35 // specifiee par des fonctions respectant le protocole ci-dessus
36 // On peut modifier la frequence de chaque tache et leur ordre d'analyse
37 // en modifiant les variables ci-dessous.
38
39 //----------
40
41 // Les taches sont dans un tableau ('nom de la tache' => periodicite)
42 // Cette fonction execute la tache la plus urgente
43 // (celle dont la date de derniere execution + la periodicite est minimale)
44 // La date de la derniere intervention est donnee par un fichier homonyme,
45 // de suffixe ".lock", modifie a chaque intervention et des le debut
46 // de celle-ci afin qu'un processus concurrent ne la demarre pas aussi.
47 // Les taches les plus longues sont tronconnees, ce qui impose d'antidater
48 // le fichier de verrouillage (avec la valeur absolue du code de retour).
49 // La fonction executant la tache est un homonyme de prefixe "genie_".
50 // Le fichier homonyme du repertoire "genie/" est automatiquement lu
51 // et il est suppose definir cette fonction.
52
53 // http://doc.spip.org/@inc_genie_dist
54 function inc_genie_dist($taches = array()) {
55 include_spip('inc/queue');
56
57 if (_request('exec')=='job_queue')
58 return false;
59
60 $force_jobs = array();
61 // l'ancienne facon de lancer une tache cron immediatement
62 // etait de la passer en parametre a ing_genie_dist
63 // on reroute en ajoutant simplement le job a la queue, ASAP
64 foreach($taches as $function=>$period)
65 $force_jobs[] = queue_add_job($function, _T('tache_cron_asap', array('function'=>$function)), array(time()-abs($period)), "genie/");
66
67 // et on passe la main a la gestion de la queue !
68 // en forcant eventuellement les jobs ajoute a l'instant
69 return queue_schedule(count($force_jobs)?$force_jobs:null);
70 }
71
72 //
73 // Construction de la liste des taches.
74 // la cle est la tache,
75 // la valeur le temps minimal, en secondes, entre deux memes taches
76 // NE PAS METTRE UNE VALEUR INFERIEURE A 30
77 // les serveurs Http n'accordant en general pas plus de 30 secondes
78 // a leur sous-processus
79 //
80 // http://doc.spip.org/@taches_generales
81 function taches_generales($taches_generales = array()) {
82
83 // verifier que toutes les taches cron sont planifiees
84 // c'est une tache cron !
85 $taches_generales['queue_watch'] = 3600*24;
86
87 // MAJ des rubriques publiques (cas de la publication post-datee)
88 // est fait au coup par coup a present
89 // $taches_generales['rubriques'] = 3600;
90
91 // Optimisation de la base
92 $taches_generales['optimiser'] = 3600*48;
93
94 // cache (chaque 10 minutes => 1/16eme du repertoire cache,
95 // soit toutes les 2h40 sur le meme rep)
96 $taches_generales['invalideur'] = 600;
97
98 // nouveautes
99 if ($GLOBALS['meta']['adresse_neuf'] AND $GLOBALS['meta']['jours_neuf']
100 AND ($GLOBALS['meta']['quoi_de_neuf'] == 'oui'))
101 $taches_generales['mail']= 3600 * 24 * $GLOBALS['meta']['jours_neuf'];
102
103 // maintenance (ajax, verifications diverses)
104 $taches_generales['maintenance'] = 3600 * 2;
105
106 // verifier si une mise a jour de spip est disponible (2 fois par semaine suffit largement)
107 $taches_generales['mise_a_jour'] = 3*24*3600;
108
109 return pipeline('taches_generales_cron',$taches_generales);
110 }
111
112 // Pas de fichier a part pour une fonction aussi petite:
113 // - elle peut retirer les fichiers perimes
114 // - elle fait appliquer le quota
115 // En cas de quota sur le CACHE/, nettoyer les fichiers les plus vieux
116 // http://doc.spip.org/@genie_invalideur_dist
117 function genie_invalideur_dist($t) {
118
119 include_spip('inc/invalideur');
120 $encore = appliquer_quota_cache();
121
122 // si le cache est trop gonfle, redemander la main pour poursuivre
123 if ($encore)
124 return (0 - $t);
125 return 1;
126 }
127
128 /**
129 * Une tache periodique pour surveiller les taches crons et les relancer si besoin
130 * quand ce cron s'execute, il n'est plus dans la queue, donc il se replanifie
131 * lui meme, avec last=time()
132 * avec une dose d'aleatoire pour ne pas planifier toutes les taches au meme moment
133 *
134 * @return int
135 */
136 function genie_queue_watch_dist(){
137 static $deja_la = false;
138 if ($deja_la) return; // re-entrance si l'insertion des jobs echoue (pas de table spip_jobs a l'upgrade par exemple)
139 $deja_la = true;
140 $taches = taches_generales();
141 $programmees = sql_allfetsel('fonction','spip_jobs',sql_in('fonction',array_keys($taches)));
142 $programmees = array_map('reset',$programmees);
143 foreach($taches as $tache=>$periode){
144 if (!in_array($tache,$programmees))
145 queue_genie_replan_job($tache,$periode,time()-round(rand(1,$periode)),0);
146 }
147 $deja_la = false;
148 return 1;
149 }
150
151 /**
152 * Replanifier une tache periodique
153 *
154 * @param string $function
155 * nom de la fonction a appeler
156 * @param int $period
157 * periodicite en secondes
158 * @param int $last
159 * date du dernier appel (timestamp)
160 * @param int $time
161 * date de replanification
162 * si null calculee automaitquement a partir de $last et $period
163 * si 0 = asap mais on n'insere pas le job si deja en cours d'execution
164 * @param int $priority
165 * priorite
166 * @return void
167 */
168 function queue_genie_replan_job($function,$period,$last=0,$time=null, $priority=0){
169 static $done = array();
170 if (isset($done[$function])) return;
171 $done[$function] = true;
172 if (is_null($time)){
173 $time=time();
174 if ($last)
175 $time = max($last+$period,$time);
176 }
177 if (!$last)
178 $last = $time-$period;
179 spip_log("replan_job $function $period $last $time $priority",'queue');
180 include_spip('inc/queue');
181 // on replanifie un job cron
182 // uniquement si il n'y en a pas deja un avec le meme nom
183 // independament de l'argument
184 queue_add_job($function, _T('tache_cron_secondes', array('function'=>$function, 'nb'=>$period)), array($last), "genie/", 'function_only', $time, $priority);
185 }
186
187
188 ?>