web-dev-qa-db-fra.com

Actualiser les flux externes uniquement dans cron?

Existe-t-il un moyen simple de s’assurer que les flux externes (via fetch_feed()) ne sont récupérés que via cron, et pas lorsqu'un utilisateur régulier visite le site? Pour des raisons de performances, je souhaite réduire le temps de chargement des pages.

Le seul moment où un flux devrait se charger dans une demande normale est probablement lorsque le cache est vide (la première fois qu'il est chargé) et peut-être lorsqu'un utilisateur connecté visite la page (car je serai le seul à posséder un compte utilisateur) .

4
Jan Fabry

Ma recommandation serait de configurer un wrapper pour fetch_feed(). Appelez la fonction wrapper via le cron de WordPress et vous ne devriez pas avoir de problème.

Donc, quelque chose comme:

function schedule_fetch_feeds() {
    if ( ! wp_next_scheduled( 'cron_fetch' ) ) {
        wp_schedule_event( time(), 'hourly', 'cron_fetch', 'http://blog1.url/feed' );
        wp_schedule_event( time(), 'hourly', 'cron_fetch', 'http://blog2.url/feed' );
    }
}

function fetch_feed_on_cron( $url ) {
    $feed = fetch_feed( $url );

    delete_transient( "feed-" . $url );

    set_transient( "feed-" . $url, $feed, 60*60 );
}

add_action( 'wp', 'schedule_fetch_feeds' );
add_action( 'cron_fetch', 'fetch_feed_on_cron', 10, 1 );

Gardez à l'esprit, Je n'ai pas encore eu l'occasion de le tester! Mais cela devrait créez des tâches cron pour récupérer chacun de vos flux et les stocker temporairement dans des transitoires. Les transitoires ont une heure d’expiration, car le cron devrait de toute façon les mettre à jour toutes les heures.

Vous pouvez extraire les flux des transitoires en utilisant:

function get_cached_feed( $url ) {
    $feed = get_transient( "feed-" . $url );
    if ( $feed ) return $feed;

    $feed = fetch_feed ( $url );
    set_transient( "feed-" . $url, $feed, 60*60 );
    return $feed;
}

Si le transitoire existe, la fonction le récupère et le renvoie. Si ce n'est pas le cas, la fonction le récupérera manuellement, le mettra en cache et le retournera quand même.

2
EAMann

Briser ma propre règle et ajouter une deuxième réponse ... mais pour une raison bien précise ...

J'ai examiné de plus près le code principal de fetch_feed() en réponse au commentaire de Rarst sur la question initiale:

saint Graal serait ici de faire en sorte que fetch_feed () natif obtienne tous les flux de manière asynchrone dans cron et jamais lorsque l’utilisateur chargera une page frontale.

Le code de fonction actuel est:

function fetch_feed($url) {
    require_once  (ABSPATH . WPINC . '/class-feed.php');

    $feed = new SimplePie();
    $feed->set_feed_url($url);
    $feed->set_cache_class('WP_Feed_Cache');
    $feed->set_file_class('WP_SimplePie_File');
    $feed->set_cache_duration(apply_filters('wp_feed_cache_transient_lifetime', 43200, $url));
    do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
    $feed->init();
    $feed->handle_content_type();

    if ( $feed->error() )
        return new WP_Error('simplepie-error', $feed->error());

    return $feed;
}

Pour vous éviter de lire sur l'objet SimplePie() ... la fonction $feed->init() vérifie d'abord si nous mettons en cache le flux et, si tel est le cas, extrait du cache plutôt que de demander à nouveau le flux de la source d'origine.

Chaque flux est mis en cache pendant 43200 secondes (ou 12 heures), soit la durée de vie du transitoire. Vous pouvez le modifier en utilisant le filtre 'wp_feed_cache_transient_lifetime'.

Pour répondre à la question initiale

Les flux ne sont pas récupérés via cron. Ils sont récupérés une fois, puis mis en cache pour une utilisation ultérieure. Le seul moment où un flux est chargé lorsqu'un utilisateur visite la page pour la première fois est lorsque le cache est vide. Pour un site très fréquenté, cela devrait être relativement rare.

Donc, si vous rencontrez des problèmes de performances liés aux flux, vous avez probablement un autre problème.

2
EAMann

Que diriez-vous de les stocker et de les garder à jour dans la table des options par le cron linux natif et de simplement les récupérer sur des pages (lecture de la base de données). De cette façon, les temps de chargement des pages ne seront pas du tout affectés.

Edit: Alrite! Si vous connaissez le fonctionnement de l'autre cron dans WordPress, créez un autre processus, puis poursuivez son travail. L'adaptation de cette approche semblerait être une bonne solution à votre cas, de même que les transitoires pour initier une telle demande.

0
Ashfame