[SPIP] ~v3.0.17-->v3.0.19
[ptitvelo/web/www.git] / www / ecrire / inc / queue.php
index 140efd8..7fa78cd 100644 (file)
@@ -3,7 +3,7 @@
 /***************************************************************************\
  *  SPIP, Systeme de publication pour l'internet                           *
  *                                                                         *
- *  Copyright (c) 2001-2012                                                *
+ *  Copyright (c) 2001-2014                                                *
  *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
  *                                                                         *
  *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
@@ -268,6 +268,7 @@ function queue_start_job($row){
  *
  * @param array $force_jobs
  *   list of id_job to execute when provided
+ * @return null|false
  */
 function queue_schedule($force_jobs = null){
        $time = time();
@@ -277,12 +278,14 @@ function queue_schedule($force_jobs = null){
        }
 
        // rien a faire si le prochain job est encore dans le futur
-       if (queue_sleep_time_to_next_job() AND (!$force_jobs OR !count($force_jobs))){
+       if (queue_sleep_time_to_next_job()>0 AND (!$force_jobs OR !count($force_jobs))){
                spip_log("queue_sleep_time_to_next_job",'jq'._LOG_DEBUG);
                return;
        }
 
        include_spip('base/abstract_sql');
+       // on ne peut rien faire si pas de connexion SQL
+       if (!spip_connect())  return false;
 
        if (!defined('_JQ_MAX_JOBS_TIME_TO_EXECUTE')){
                $max_time = ini_get('max_execution_time')/2;
@@ -343,6 +346,7 @@ function queue_schedule($force_jobs = null){
        else
                queue_update_next_job_time();
 
+       return true;
 }
 
 /**
@@ -473,9 +477,9 @@ function queue_set_next_job_time($next) {
        // toujours relire la valeur pour comparer, pour tenir compte des maj concourrantes
        // et ne mettre a jour que si il y a un interet a le faire
        // permet ausis d'initialiser le nom de fichier a coup sur
-       $curr_next = $_SERVER['REQUEST_TIME'] + queue_sleep_time_to_next_job(true);
+       $curr_next = $_SERVER['REQUEST_TIME'] + max(0,queue_sleep_time_to_next_job(true));
        if (
-                       ($curr_next<$time AND $next>$time) // le prochain job est dans le futur mais pas la date planifiee actuelle
+                       ($curr_next<=$time AND $next>$time) // le prochain job est dans le futur mais pas la date planifiee actuelle
                        OR $curr_next>$next // le prochain job est plus tot que la date planifiee actuelle
                ) {
                if (include_spip('inc/memoization') AND defined('_MEMOIZE_MEMORY') AND _MEMOIZE_MEMORY) {
@@ -501,8 +505,9 @@ function queue_set_next_job_time($next) {
 function queue_affichage_cron(){
        $texte = "";
 
+       $time_to_next = queue_sleep_time_to_next_job();
        // rien a faire si le prochain job est encore dans le futur
-       if (queue_sleep_time_to_next_job() OR defined('_DEBUG_BLOCK_QUEUE'))
+       if ($time_to_next>0 OR defined('_DEBUG_BLOCK_QUEUE'))
                return $texte;
 
        // ne pas relancer si on vient de lancer dans la meme seconde par un hit concurent
@@ -511,43 +516,78 @@ function queue_affichage_cron(){
        @touch($lock);
 
        // il y a des taches en attentes
+       // si depuis plus de 5min, on essaye de lancer le cron par tous les moyens pour rattraper le coup
+       // on est sans doute sur un site qui n'autorise pas http sortant ou avec peu de trafic
+       $urgent = false;
+       if ($time_to_next<-300)
+               $urgent = true;
 
        $url_cron = generer_url_action('cron','',false,true);
 
-       // Si fsockopen est possible, on lance le cron via un socket
-       // en asynchrone
-       if(function_exists('fsockopen')){
-               $parts=parse_url($url_cron);
-
-               $fp = @fsockopen($parts['host'],
-               isset($parts['port'])?$parts['port']:80,
-               $errno, $errstr, 30);
-
-               if ($fp) {
-                       $query = $parts['path'].($parts['query']?"?".$parts['query']:"");
-                       $out = "GET ".$query." HTTP/1.1\r\n";
-                       $out.= "Host: ".$parts['host']."\r\n";
-                       $out.= "Connection: Close\r\n\r\n";
-                       fwrite($fp, $out);
-                       fclose($fp);
-                       return $texte;
-               }
-       }
+       if (!defined('_HTML_BG_CRON_FORCE') OR !_HTML_BG_CRON_FORCE){
+
+               // methode la plus rapide :
+               // Si fsockopen est possible, on lance le cron via un socket en asynchrone
+               // si fsockopen echoue (disponibilite serveur, firewall) on essaye pas cURL
+               // car on a toutes les chances d'echouer pareil mais sans moyen de le savoir
+               // on passe direct a la methode background-image
+               if(function_exists('fsockopen')){
+                       $parts=parse_url($url_cron);
+
+                       switch ($parts['scheme']) {
+                               case 'https':
+                                       $scheme = 'ssl://';
+                                       $port = 443;
+                                       break;
+                               case 'http':
+                               default:
+                                       $scheme = '';
+                                       $port = 80;
+                       }
 
-       // ici lancer le cron par un CURL asynchrone si CURL est present
-       if (function_exists("curl_init")){
-               //setting the curl parameters.
-               $ch = curl_init($url_cron);
-               curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-               // cf bug : http://www.php.net/manual/en/function.curl-setopt.php#104597
-               curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
-               // valeur mini pour que la requete soit lancee
-               curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100);
-               // lancer
-               curl_exec($ch);
-               // fermer
-               curl_close($ch);
-               return $texte;
+                       $fp = @fsockopen($scheme.$parts['host'],
+                       isset($parts['port'])?$parts['port']:$port,
+                       $errno, $errstr, 1);
+
+                       if ($fp) {
+                               $timeout = 200; // ms
+                               stream_set_timeout($fp,0,$timeout * 1000);
+                               $query = $parts['path'].($parts['query']?"?".$parts['query']:"");
+                               $out = "GET ".$query." HTTP/1.1\r\n";
+                               $out.= "Host: ".$parts['host']."\r\n";
+                               $out.= "Connection: Close\r\n\r\n";
+                               fwrite($fp, $out);
+                               spip_timer('read');
+                               $t = 0;
+                               // on lit la reponse si possible pour fermer proprement la connexion
+                               // avec un timeout total de 200ms pour ne pas se bloquer
+                               while (!feof($fp) AND $t<$timeout) {
+                                       @fgets($fp, 1024);
+                                       $t += spip_timer('read',true);
+                                       spip_timer('read');
+                               }
+                               fclose($fp);
+                               if (!$urgent)
+                                       return $texte;
+                       }
+               }
+               // si fsockopen n'est pas dispo on essaye cURL :
+               // lancer le cron par un cURL asynchrone si cURL est present
+               elseif (function_exists("curl_init")){
+                       //setting the curl parameters.
+                       $ch = curl_init($url_cron);
+                       curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+                       // cf bug : http://www.php.net/manual/en/function.curl-setopt.php#104597
+                       curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
+                       // valeur mini pour que la requete soit lancee
+                       curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
+                       // lancer
+                       curl_exec($ch);
+                       // fermer
+                       curl_close($ch);
+                       if (!$urgent)
+                               return $texte;
+               }
        }
 
        // si deja force, on retourne sans rien