Refresh external feeds only in cron?

Is there an easy way to ensure that external feeds (via fetch_feed()) are only fetched via cron, and not when a regular user visits the site? This is for performance reasons, I want to minimize the page load time.

The only time a feed should load in a normal request are probably when the cache is empty (the first time it is loaded) and maybe when a logged in user is visiting the page (because I will be the only one with a user account).

3 Answers
3

My recommendation would be to set up a wrapper for fetch_feed(). Call the wrapper function through WordPress’ cron and you shouldn’t have an issue.

So something like:

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

Keep in mind, I haven’t had a chance to test this yet! But it should create cron jobs to grab each of your feeds and store the feeds temporarily in transients. The transients have 1-hour expirations, because the cron should realistically be updating them every hour anyway.

You can pull the feeds out of the transients using:

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

If the transient exists, the function grabs it and returns it. If it doesn’t, the function will grab it manually, cache it, and still return it.

Leave a Comment