wordpressのwp-cronを理解する

先日の記事で十分理解できていなかったところが、よくよく調べてみると英語で色々と公式のドキュメントを見つけたので一つ一つ読んでみます。

そもそもwp-cronとは

こちらの記事を読んでの内容になります。

Cron

なぜwp-cronを使うのか

こちらが歴史的な経緯とかが書いてあって面白かったです。
普通に考えれば unix システムが提供する cron を使用できればそれで十分ですよね。でもあえて wp-cron を利用するには理由がちゃんとあります。
それは共有サーバなどでは、システム権限が与えられないこともあるからです。
ですが当然アプリケーション側からスケジューリング処理を実施したいという要望は当然あるため、cron は使えないけれどもスケジューリングを実施したいという要望を解決するために wp-cron は設計されているようです。

wp-cron はページロードをフックにして何をしているのか

また、記事中の下記の記述が少し気になりました。

WP-Cron works by: on every page load, a list of scheduled tasks is checked to see what needs to be run. Any tasks scheduled to be run will be run during that page load. WP-Cron does not run constantly as the system cron does; it is only triggered on page load. Scheduling errors could occur if you schedule a task for 2:00PM and no page loads occur until 5:00PM.

「スケジュールされたタスクはページロードの間に起動される」という記述があるんですよね。
起動される・・・というのが具体的にどの範囲までを言うのかわかりませんが、リクエストを返却するまでにすべてのタスクが終了するのは待つんだろうか・・・?
普通に考えたらそういうふうになるのは考えにくいのですが、詳細に調べる必要がありそうです。

同様に最後の段落に下記のような記述があります。

With a system cron if the time passes and the task did not run it is lost and will never run. WP-Cron will run tasks regardless of how old they are. Tasks will sit in a queue until a page is loaded to trigger them, thus no task will ever be lost.

wp-cron ではページロードを行ってから実行されるまでにタスクはキューに入れられて管理されるようです。そのためタスクが損失することはないとも言っていますね。
ということは、合わせて考えるとページロードする時点ではタスクをキューに入れておくのかな、キューから引っ張ってきてタスクを実行するプロセスはまた別に存在するのかもしれませんね。

先に wp-cron.php を読み込んだ記事を書きましたが、その知識と合わせてみると意外とその線で間違っていないと思います。
なぜなら各タスクを実際に処理する実装は wp-cron.php に集約されています。またそのときにタスクのキューの情報は直接 transition API を経由して DB から取得してきています。
イメージとしてはページロードの時点ではタスクキューの調整だけをやると思います、それに続けて非同期的に wp-cron.php を http リクエストかなんかでキックしているんじゃないかなと。そうすると wp-cron.php の GETリクエスト にロックファイルのタイムスタンプがあるのはこのケースでの起動フローなんじゃないかなと考えると納得できます。

まあ予測はこのあたりにしてドキュメントを読んだりソースを読むことを進めたいと思います。

wp-cronの基本

こちらの記事を読んでの内容になります。

Understanding WP-Cron Scheduling

wordpress の疑似cron(以下 wp-cron と記述します) では unix の cron と少しスケジューリングのタイミングが異なります。
通常の cron では毎時5分に実施などの指定を行うのに対して、 wp-cron では例えば2時から5分毎に実施などのスケジューリングが可能です。
このときには 2:00 -> 2:05 -> 2:10 とタスクが実行されます。

またデフォルトでは wordpress では

  • hourly
  • twicedaily
  • daily

という interval を提供します。ただし下記のようにカスタムインターバルというのも自分で作成することが可能なので、特に複雑になるようなことはなさそうです。
interval で指定した値は秒数として解釈されます。

add_filter( 'cron_schedules', 'example_add_cron_interval' );

function example_add_cron_interval( $schedules ) {
    $schedules['five_seconds'] = array(
        'interval' => 5,
        'display'  => esc_html__( 'Every Five Seconds' ),
    );

    return $schedules;
}

正確な wp-cron の実施

こちらの記事を読んでの内容になります。

Hooking WP-Cron Into the System Task Scheduler

wp-cron は先にも述べたように、時間に正確に動作するわけではありません。ページをロードすることをフックにしないと行けないので時間どおりに実施することが保証されません。
どうしても時間に正確な wp-cron を実施する必要がある場合は、システム cron を利用することで解決できるようです。

その場合は通常のページロードをフックにしてスケジューリングを行う処理を無効にする必要があり、下記のように wp-config.php へと追記します

define('DISABLE_WP_CRON', true);

加えて cron のスケジューリングに wp-cron.php へと http リクエストを送るような設定を行えば完了となります。

ただこれはちょっとパラドックス感がありますね。冒頭で wp-cron を利用する理由は cron が利用できないからという背景がありました。
まあ wordpress のアプリケーションコンテキストを利用したバッチ処理などを拡張しやすいので、この形でも全然ありだと思います。

まとめ

だんだんと wp-cron について理解できてきました。
また新しいドキュメントなど見つければ確認しつつ実装の方も確認してみたいと思います。

  • ページロード時にスケジュールタスクのキューを生成するところ
  • スケジュールタスクをさばく wp-cron.php を叩いているところ

少なくともコチラについては実装まで把握できるようにしたいと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください