WordPress Cron Job Tricks

If you’re familiar with WordPress Cron Job, you may already know the fact that wordpress cron job isn’t real cron job. It’s triggered by visitor.

What if your site is just like mine, nobody paid a visit?

Here is a trick for webmasters:

UptimeRobot is a Free Website Uptime Monitoring service which will monitor your site every 5 minutes. Other than ping, it also supports HTTP as monitor type.

HTTP monitor type, you get my point?

Here is another trick for developer:

It is possible that multiple instances of your cron job are running at the same time. For example, if you have used Autoblog plugin before, you probably experience the duplicate posts issue even though the autoblog claims it does have duplicate posts eraser feature.

The thing deep down is actually if multiple visitors come to your site, there is a chance that your cron job will be executed in parallel. So, how to stop this?

Well, if you are a decent developer, you may think of Lock.

Most of the time, PHP developers will use file lock and there is a PHP function called flock. But flock are not so reliable and may go wrong somehow, therefore, some people will Just create a file on script start and delete it in the end.

Another similar way is database.

if( get_transient( 'my_cron_job_lock' ) == 'locked' )
    return false;

set_transient( 'my_cron_job_lock', 'locked', 60*5 ); //5 mins

//executing cron job here

delete_transient( 'my_cron_job_lock' );

Actually, I don’t like to use WordPress Cron Job. Sometimes, the cron job didn’t fire on time.

So, if clients are very sensitive to the execution time, then I’ll switch to anther way. It’s also how WordPress does, doing the job by comparing current time to last job execution time.

Here is the code from how WordPress handles plugin update check.

add_action( 'admin_init', '_maybe_update_plugins' );
function _maybe_update_plugins() {
    $current = get_site_transient( 'update_plugins' );
    if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) )
        return;
    wp_update_plugins();
}

Don’t get me wrong. WordPress actually add wp_update_plugins to its cron job queue.

if ( !wp_next_scheduled('wp_update_plugins') && !defined('WP_INSTALLING') )
        wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins');

Interesting, right?


Update: 2013-07-31

Lately, I’ve tests different locking methods:

database: simply not working. cron job overlay still happens.

file locking: flock($fp, FLOCK_EX | FLOCK_NB) . someone will take the lock forever and FLOCK_NB is not available at windows.

file presence: almost perfect.

            $lock_file = $this->getLockFile();
            if(!file_exists($lock_file)){
                touch($lock_file);
            }else{
                $interval = absint(get_option(MY_CRON_INTERVAL)) * 59;
                if(time() - filectime($lock_file) > $interval){
                    unlink($lock_file);
                    touch($lock_file);
                }else
                    return ;

            }

Well, I’ve seen some articles telling me writing PID to the file and compare the PID everytime. But I actually don’t like it because it uses exec function. You don’t know if your hosting will be disable such dangerous function or not.

So, it seems it’s very hard to prevent cron job from overlaying. Maybe I should look for real cron job?

Create a special cron job URL along with magic token and put the URL into cron job

Share and Enjoy

    FacebookTwitterGoogle PlusLinkedInStumbleUponPinterestRedditTumblrDiggEmailPrint

Related Posts