Exemplo n.º 1
0
/**
 * 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;
}
Exemplo n.º 2
0
/**
 * 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;
}
Exemplo n.º 3
0
/**
 * 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;
}