web-dev-qa-db-ja.com

ページの読み込みを妨げずにcronタスクを実行しますか?

私はユーザが管理領域のAJAXを介して投稿の添付ファイルをアップロードすることを可能にするプラグインを持っています。私は後で それらのREST AP​​I を通してDropBoxにこれらのファイルをプッシュしようとします。それはほぼは動作します。問題は、実行中にページの読み込みを妨げるWP cronタスク Push to DropBoxが終了するまで (これには最大30分かかります。大きなファイル)。

私は似たような質問( はこちらはこちら )を見ましたが、後者は、これらのcronタスクが、実際には、タスクの実行中にページが正しくロードされるのを妨げることを意味します。

ページの読み込みがcronタスクの実行によって影響を受けないように設定することは可能ですか?おそらく私はそれを正しいやり方でやっていません。

これが私のプラグインの関連部分です:

function __construct() {

    add_action( 'wp_ajax_my_admin_upload_attachment', array( $this, 'my_admin_upload_attachment') );
    add_action('my_Push_to_dropbox', array($this,'Push_to_dropbox'));

} // end constructor

function my_admin_upload_attachment() {
    /* upload and save file locally, update post meta */
    /* schedule the files to be uploaded to DropBox */
    wp_schedule_single_event(time()+5, 'my_Push_to_dropbox');
    /* return success JSON */
}

function Push_to_dropbox() {
    $this->log('Push_to_dropbox - started.');
    //$this->do_Push_to_dropbox();
    @ignore_user_abort(true); // this does not help: 'finished' message still never prints
    set_time_limit(0);
    sleep(30); // this mimicks the long-running upload task
    $this->log('Push_to_dropbox - finished.');
}

EDIT:wp-config.phpからdefine('ALTERNATE_WP_CRON', true);を削除しました。今度はページは遅れることなくロードされますが、cronタスクは連続するページ更新によって中断されます。上記の'finished')メッセージはログに表示されません。

4
montrealist

Cronタスクは、0.01秒のタイムアウト以外にページロードに直接影響することはありません(もちろん、サーバーロードに影響を与えるため、ページロードに影響を与える可能性があります間接的に)。

私の口実はあなたのPHP設定が問題であるということです。 cronタスクは他のWeb要求と同じように実行され、それらはPHPのmax_execution_time INI設定の影響を受けます。これが90秒に設定されていると、リクエストは終了し、ファイルは同期されません。これをテストするには、sleepを自分のmax_execution_timeよりも小さい数値に設定し、それが終了するかどうかを確認します。

その場合は、追加してみることができます。

ini_set( 'max_execution_time', 0 );

Push_to_dropbox()関数の先頭にすべてのホストで機能するわけではないので、これは優れた解決策ではありませんが、それは出発点です。

2
Matthew Boynes

WP Plugin Handbook によると、「実行予定のタスクはすべて、そのページの読み込み中に実行されます。」したがって、常にページの読み込みが遅くなるため、ユーザーが待つ必要のない大きなタスクの場合は、実際のCRON(またはスケジュールされたタスク)を直接置き換えるのに使用しないでください。

より良い解決策は、バックグラウンドで作業を行う非同期タスクを起動するWP Cronタスクを設定することです - thisのようなライブラリで最も簡単に行われる1 。これにより、ユーザーはプロセスが終了するのを待つ必要がなくなり、ユーザーが切断してもプロセスは強制終了されません。

あるいは、 AWS Lambda または CronJob.org のようなサービスを使用してプロセスを開始することもできます。

1
Justin Waulters