Jan 29
Run Wordpress tasks from real cron job
I had to pull off my sleeves, open WP code and see by myself because all I finally found was this article (well I must admit that it was very helpful):
http://wordpress.org/support/topic/273381
To explain, in short, how Wordpress crons are working, here is a shortened call stack:
- Web User Request
- => WP API initialisation
- ==> wp_cron() // if authorized to run, the cron array is loaded (from a get_option call)
- ===> spawn_cron() // this is called if a job pending execution is found in the cron array.
- ====> wp_remote_post(’wp-cron.php?doing_wp_cron’) // the asynchronous call
wp_cron() is the function that initiate the process of executing the jobs if one needs to be executed. And wp-cron.php is the one that will, at the end, execute those jobs.
In order to run the jobs from a real cron, it is simple as scheduling a wget call to wp-cron.php and disabling PHP calls to wp_cron() function. Damn, if I knew that from beginning… When you open the wp_cron() function declaration, you will notice that first line checks for a constant definition: DISABLE_WP_CRON. So you define(’DISABLE_WP_CRON’, true) in your wp-config.php and that’s it.
Well, if you are using Wordpress MU, that’s not totally it. Remember the comments in the stack call above? The cron array is loaded from a function call to get_option. In Wordpress MU, get_option reads data from wp_xx_options which is per blog database table. So it has a set of scheduled tasks per blog. So you need to call wp-cron.php in the context of each blog. So it’s starting to bug me… I don’t want to do maintenance tasks everytime a blog is created in Wordpress MU! To prevent this, I created a small php script that I called wp-cron-multi-blog.php that is calling wp-cron.php for each active blogs defined in Wordpress MU.
Here is a wrap-up of the information without the bells and whistles. To run WP tasks from a real scheduled cron you should do this:
in wp-config.php, add the following line :
define('DISABLE_WP_CRON', true);
for a standard Wordpress installation, configure a crontab that:
wget http://www.server.com/wp-cron.php?doing_wp_cron
for a Wordpress MU installation, configure a crontab per blog like:
wget http://www.server.com/wp-cron.php?doing_wp_cronwget http://www.server.com/whatever/wp-cron.php?doing_wp_cronwget http://www.server.com/what-a-blogger/wp-cron.php?doing_wp_cron...
or, a single crontab calling my wp-cron-multi-blog.php (placed in root installation of WP):
wget http://www.server.com/wp-cron-multi-blog.php
A final note about wp-cron-multi-blog.php. If your Wordpress MU installation has a lot of blogs and each of them tends to have many time consuming tasks (ex: cache cleaning), it may be a good idea to edit this script in order to limit the number of blogs to run for at one time.
Hope this helps.
Pascal.
Pages: 1 2
4 comments
I implemented this in WPMU 2.9.1.1 with the wp-cron-multi-blog.php script and a /etc/crontab setup and it does not work at all for me. If I manually browse to the script, it reports back as if its working/doing something, but doesn’t appear to actually spawn the cron jobs.
Ok I will double-check it in case I did a copy/paste mistake.
What are your cron jobs skipped? pre-publishing?
Pascal.
Thank you for this post. It helped me alot
You can probably make your script more efficient by managing the list of scheduled task, or the blog which has them, in a separate DB table.
Another enhancement might be to directly call the WP cron task execution API, after calling switch_to_blog for the appropriate blog number.