Atualizar feeds externos somente no cron?

4

Existe uma maneira fácil de garantir que os feeds externos (via fetch_feed() ) sejam buscados somente pelo cron e não quando um usuário comum visita o site? Por motivos de desempenho, quero minimizar o tempo de carregamento da página.

A única vez que um feed deve ser carregado em uma solicitação normal provavelmente é quando o cache está vazio (a primeira vez que é carregado) e talvez quando um usuário conectado está visitando a página (porque eu serei o único com um conta de usuário).

    
por Jan Fabry 21.02.2011 / 17:24

3 respostas

2

Minha recomendação seria configurar um wrapper para fetch_feed() . Chame a função wrapper através do cron do WordPress e você não deve ter um problema.

Então, algo como:

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 );

Lembre-se, eu ainda não tive a chance de testar isso! Mas deve criar trabalhos agendados para pegar cada um dos seus feeds e armazenar os feeds temporariamente em transientes. Os transientes têm expirações de 1 hora, porque o cron deve realisticamente atualizá-las a cada hora de qualquer maneira.

Você pode retirar os feeds dos transientes usando:

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;
}

Se o transitório existir, a função agarra-o e retorna-o. Se isso não acontecer, a função irá pegá-lo manualmente, armazená-lo em cache e ainda devolvê-lo.

    
por EAMann 24.02.2011 / 19:28
2

Quebrar minha própria regra e adicionar uma segunda resposta ... mas por um motivo muito específico ...

Analisei mais de perto o código principal para fetch_feed() em resposta ao comentário de Rarst sobre a pergunta original:

  

holy grail aqui seria fazer o fetch_feed () nativo obter todos os feeds de forma assíncrona no cron e nunca quando o usuário carrega a página front-end

O código da função atual é:

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;
}

Para poupar o trabalho de ler o objeto SimplePie() ... a função $feed->init() primeiro verifica se estamos armazenando o feed em cache e, em caso afirmativo, recupera do cache

Cada alimentação é armazenada em cache por 43200 segundos (ou 12 horas), que é o tempo de vida do transiente. Você pode modificar isso para cima ou para baixo usando o filtro 'wp_feed_cache_transient_lifetime'.

Para resolver a questão original

Feeds não são revistos através do cron. Eles são buscados uma vez e depois armazenados em cache para uso futuro. A única vez que um feed é carregado quando um usuário visita a página pela primeira vez é quando o cache está vazio. Para um site de tráfego intenso, isso deve ser relativamente raro.

Então, se você estiver enfrentando problemas de desempenho relacionados a feeds, provavelmente terá outro problema em andamento.

    
por EAMann 24.02.2011 / 21:44
0

Que tal você armazenar & mantenha-os atualizados na tabela de opções pelo cron linux nativo e apenas busque nas páginas (leitura do banco de dados). Desta forma, os tempos de carregamento da página não serão afetados.

Editar: Alitar! Se você estiver familiarizado com o modo como o cron alternativo funciona no WordPress criando outro processo e continue com seu trabalho. Adaptar essa abordagem parece ser uma boa solução para o seu caso, juntamente com transientes, para iniciar tal solicitação.

    
por Ashfame 25.02.2011 / 20:16