「WP Background Processing」を使ってWordPressの重い処理をバックグランドで行なう
WordPressでWebアプリを作る際に、数十分以上時間がかかる等の重い処理を書きたい時がある。
しかし、素直に処理を書いていくと、 その処理が完了するまでユーザーは待つ必要があるし、 そもそもブラウザがタイムアウトを起こしてしまい、処理が途中で止まってしまう問題 がある。
このWordPressの問題を回避するために「WP Background Processing」と言うライブラリがある。
今回は、このWP Background Processingの使い方について解説していく。
deliciousbrains/wp-background-processing: WordPress background processing class
WP Background Processingとは?
「WP Background Processing」とは、 ノンブロッキングの非同期リクエストを通して、WordPressでバックグランド処理、非同期処理を実現 するためのライブラリである。
ライブラリなので、composerでインストールすることでどのプラグイン、テーマでも使う事ができる。
使い方としては、上述した様に、数十分以上かかるような重い処理を管理画面から実行したい時に役に立つ。
WP Background Processingのインストトール
インストールは、以下のコマンドをすればOK.
composer require deliciousbrains/wp-background-processing
WP Background Processingの使い方
WP Background Processingには、「Async Request」と「Background Process」の2つのクラスが用意されており、 いずれかのクラスをextendsしたクラスを作る、と言う方法で使う。
この2つのクラスの使い分けだが、以下の様に使い分けると良い。
- Async Request .. 1つのタスクを処理したい時
- Background Process .. 複数のタスクを処理したい時
例えば、「メールアドレスを30人のユーザーに送りたい」と言う1つのタスクをしたい場合は、Async Requestが便利だ。
逆に、「記事を加工して→記事を公開状態にして→記事をTwitterでツイートする」の様に複数のタスクをしたり、 「10万件の記事を加工する」の様に重い処理を小分けにしたい場合は、Background Processが良い。
以下は、それぞれのクラスの使い方を解説していく。
Async Requestの使い方
Async Requestの使い方を説明するために、まずはWP_Example_Requestを作成して、 そのWP_Example_Requestをどのように使うのかを説明していく。
class WP_Example_Request extends WP_Async_Request {
    /**
     * ajaxのaction
     * 
     * @var string
     */
    protected $action = 'example_request';
    /**
     * Handle
     */
    protected function handle() {
        // ここに非同期で実行したい処理を書く。
        $post_count = $_POST["post_count"];
        // 最後にこれを書く。
        wp_die();
    }
}
ポイントは$action変数を定義することと、handleメソッドの実装をすること。
$actionは、WordPressのajaxでのリクエストを処理する時に使うもので、一意になるように設定すると良い。
handleメソッドは、実際に非同期リクエストを送った時に実行されるメソッドになる。
上記で作成したクラスは以下の様に使う。
function execute(){
    $process = new WP_Example_Request();
    $process->data(["post_count" => 15])->dispatch();
}
dataメソッドは非同期リクエストの際に一緒に送りたいデータを入れることができる。dataメソッドで送ったデータは、
WP_Example_Requestクラスのhandleメソッドで取り出すことができる。
dispatchメソッドは、実際に非同期リクエストを送るためのメソッドだ。
Background Processの使い方
class WP_Example_Process extends WP_Background_Process {
    /**
     * @var string
     */
    protected $action = 'example_process';
    /**
     * Task
     *
     * WP_Async_Requestではhandleメソッドを作ったが、
     * WP_Background_Processではtaskを作成する。
     */
    protected function task( $item ) {
        $post_id = $item["post_id"];
        // Actions to perform
        // wp_dieではなくreturn falseで処理を終える。
        return false;
    }
    /**
     * Complete
     *
     * 任意で定義できるメソッド
     */
    protected function complete() {
        parent::complete();
        // Show notice to user or perform some other arbitrary task...
    }
}
以下の様に実行する。
function execute(){
    $process = new WP_Example_Process();
    $posts = get_posts();
    foreach($posts as $post){
        $process->push_to_queue(["post_id" => $post->ID]);
    }
    $process->save()->dispatch();
}
WP_Background_Processを使うためには、push_to_queueメソッドを通してタスクに渡すデータを用意する。
push_to_queueで渡されたデータはWP_Example_Processのtaskメソッドの引数として渡される。
$process->save()によってpush_to_queue()で渡されたデータをデータベースに保存し、その後、
dispatch()で非同期リクエストを送る。
