/** * Déclenche le cron en asynchrone ou retourne le code HTML pour le déclencher * * Retourne le HTML à ajouter à la page pour declencher le cron * ou rien si on a réussi à le lancer en asynchrone. * * Un verrou (cron.lock) empêche l'exécution du cron plus d'une fois par seconde. * * @uses queue_sleep_time_to_next_job() * @see action_cron() L'URL appelée pour déclencher le cron * * @return string */ 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 ($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 if (file_exists($lock = _DIR_TMP . "cron.lock") and !(@filemtime($lock) < $_SERVER['REQUEST_TIME'])) { return $texte; } @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); 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; } $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; } } } 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 if (defined('_DIRECT_CRON_FORCE')) { return $texte; } // si c'est un bot // inutile de faire un appel par image background, // on force un appel direct en fin de hit if (defined('_IS_BOT') and _IS_BOT) { define('_DIRECT_CRON_FORCE', true); return $texte; } // en derniere solution, on insere une image background dans la page $texte = '<!-- SPIP-CRON --><div style="background-image: url(\'' . generer_url_action('cron') . '\');"></div>'; return $texte; }
/** * Gérer le lancement du cron si des tâches sont en attente * * Cette fonction est appelée par le pipeline affichage_final * * @param string $texte Contenu de la page envoyée au navigateur * @return string Contenu de la page envoyée au navigateur */ function f_queue(&$texte) { // eviter une inclusion si rien a faire if (_request('action') == 'cron' or queue_sleep_time_to_next_job() or defined('_DEBUG_BLOCK_QUEUE')) { return $texte; } include_spip('inc/queue'); $code = queue_affichage_cron(); // si rien a afficher // ou si on est pas dans une page html, on ne sait rien faire de mieux if (!$code or !$GLOBALS['html']) { return $texte; } // inserer avant le </body> fermant si on peut, a la fin de la page sinon if (($p = strpos($texte, '</body>')) !== FALSE) { $texte = substr($texte, 0, $p) . $code . substr($texte, $p); } else { $texte .= $code; } return $texte; }
/** * Déclenche le cron en asynchrone ou retourne le code HTML pour le déclencher * * Retourne le HTML à ajouter à la page pour declencher le cron * ou rien si on a réussi à le lancer en asynchrone. * * @return string */ function queue_affichage_cron() { $texte = ""; // rien a faire si le prochain job est encore dans le futur if (queue_sleep_time_to_next_job() or defined('_DEBUG_BLOCK_QUEUE')) { return $texte; } // il y a des taches en attentes $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; } } // ici lancer le cron par un CURL asynchrone si CURL est pr�sent 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; } // si deja force, on retourne sans rien if (defined('_DIRECT_CRON_FORCE')) { return $texte; } // si c'est un bot // inutile de faire un appel par image background, // on force un appel direct en fin de hit if (defined('_IS_BOT') and _IS_BOT) { define('_DIRECT_CRON_FORCE', true); return $texte; } // en derniere solution, on insere une image background dans la page $texte = '<!-- SPIP-CRON --><div style="background-image: url(\'' . generer_url_action('cron') . '\');"></div>'; return $texte; }