web-dev-qa-db-ja.com

Cronでのみ外部フィードを更新しますか?

fetch_feed()を介した)外部フィードがcronを介してのみ取得され、通常のユーザーがそのサイトにアクセスしたときには取得されないようにする簡単な方法はありますか?これはパフォーマンス上の理由から、ページの読み込み時間は最小限に抑えたいと思います。

通常のリクエストでフィードがロードされるのは、キャッシュが空のとき(最初にロードされたとき)と、ログインユーザーがページにアクセスしたとき(おそらく、私がユーザーアカウントを持つ唯一のユーザーになるため)です。 。

4
Jan Fabry

私のお勧めはfetch_feed()のラッパーを設定することです。 WordPressのcronを使ってラッパー関数を呼び出しても問題ありません。

だから、のようなもの:

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

覚えておいてください、私はまだこれをテストする機会がありませんでした!しかしそれはすべきですそれぞれのフィードを取得して一時的にそのフィードを一時的に保存するcronジョブを作成します。とにかくクーロンは現実的には1時間ごとに更新する必要があるため、トランジェントの有効期限は1時間です。

あなたはトランジェントからフィードを引き出すことができます:

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

トランジェントが存在する場合、関数はそれを取得して返します。もしそうでなければ、関数はそれを手動でつかみ、それをキャッシュし、そしてそれをなおも返すでしょう。

2
EAMann

自分のルールを破って2番目の答えを追加しています...しかし非常に具体的な理由のために...

最初の質問に対するRarstのコメントを受けて、fetch_feed()の実際のコアコードを詳しく調べました。

ここでの聖杯は、ネイティブのfetch_feed()がすべてのフィードをcronで非同期に取得し、ユーザーがフロントエンドページをロードしたときに決して取得しないようにすることです。

実際の機能コードは次のとおりです。

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

SimplePie()オブジェクトを読み上げる手間を省くために、$feed->init()関数は最初にフィードをキャッシュしているかどうかを確認し、もしそうなら、キャッシュから取得します元のソースからフィードを再要求するのではなく。

各フィードは43200秒間(または12時間)キャッシュされています。これはトランジェントの寿命です。 'wp_feed_cache_transient_lifetime'フィルタを使用して、これを上下に変更できます。

元の質問に対処する

フィードはcronを介して再取得されません。それらは一度取得され、そして将来の使用のためにキャッシュされます。ユーザーが最初にページにアクセスしたときにフィードがロードされるのは、キャッシュが空のときだけです。トラフィックの多いサイトでは、これは比較的まれです。

ですから、フィードに関連したパフォーマンスの問題に直面しているのなら、おそらく他の問題が起こっているでしょう。

2
EAMann

あなたはどうやってそれらをネイティブのlinux cronによってoptionsテーブルに更新して保存し続け、そして単にページにフェッチする(データベース読み込み)。これにより、ページの読み込み時間はまったく影響を受けません。

編集:Alrite!別のプロセスを作成して代替cronがWordPressでどのように機能するかをよく知っていて、その作業を続ける場合。そのようなアプローチを採用することは、そのような要求を開始するための過渡現象と共にあなたのケースに対する良い解決策であるように思われるでしょう。

0
Ashfame