I have a plugin that lets users upload post attachments via AJAX in the admin area. I later try to push these files to DropBox via their REST API. It almost works. The issue is with WP cron task which, when running, prevents the page from loading until the push to DropBox finishes (which can take up to 30 minutes for larger files).
I’ve looked at similar questions (here and here), but the latter implies that these cron tasks do, indeed, prevent the page from loading properly as the task is running.
Is it possible to set it up so that page loads are unaffected by cron task executions? Perhaps I’m not doing it the right way.
Here are the relevant bits of my plugin:
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: removed define('ALTERNATE_WP_CRON', true);
from wp-config.php
, now the pages load without delay, but cron task gets interrupted by successive page refreshes: the ‘finished’ message above doesn’t get printed in the log.
Cron tasks don’t directly affect page load besides the 0.01s timeout (of course, they do affect server load, so they can impact page load indirectly).
My hunch is that your PHP config is the issue. The cron tasks run like any other web request, and they’re subject to PHP’s
max_execution_time
INI setting. If this is set to, say, 90 seconds, then the request will die and your files won’t sync. You can test this by settingsleep
to a lower number than yourmax_execution_time
, and see if it finishes.If that is the case, you can try adding:
to the top of your
push_to_dropbox()
function. It’s not a great solution, because it won’t work on every host, but it’s a start.According to the WP Plugin Handbook “Any tasks scheduled to be run will be run during that page load.” Thus, it will always slow down the page load and should not be used to directly replace an actual CRON (or scheduled task) for large tasks that the user should not have to wait for.
A better solution is to set up a WP Cron task to fire off an asynchronous task that will do the work in the background – most easily done with a library such as this one. This way the user will not have to wait for the process to finish, and the process will not be killed if the user disconnects.
Alternatively, one could use a service like like AWS Lambda or CronJob.org to kick off the process.