[wp-hackers] post_status = future and pseudo-cron

Ryan Boren ryan at boren.nu
Fri Feb 10 20:05:22 GMT 2006


Owen Winkler wrote:
> My vote - Forget the unix cron crap and make this simple:

Hear, hear.

I took what you provided and added some simple hourly and daily 
recurrence.  More complicated recurrence can be done using the method 
you suggested.  This was briefly tested and seemed to be fairly sane.

function wp_schedule_event($timestamp, $recurrence, $hook) {
	$args = array_slice(func_get_args(), 3);
	$crons = get_option('cron');
	$crons[$timestamp][$hook] = array('recur' => $recurrence, 'args' => $args);
	ksort($crons);
	update_option('cron', $crons);
}

function wp_unschedule_event($timestamp, $hook) {
	$crons = get_option('cron');
	unset($crons[$timestamp][$hook]);
	if ( empty($crons[$timestamp]) )
		unset($crons[$timestamp]);
	update_option('cron', $crons);
}

function wp_clear_scheduled_hook($hook) {
	while($timestamp = next_scheduled('scheduled_hook'))
		wp_unschedule_event($timestamp, 'scheduled_hook');
}

function next_scheduled($hook) {
	$crons = get_option('cron');
	if ( empty($crons) )
		return false;
	foreach($crons as $timestamp => $cron) {
		//if($timestamp <= time()) continue;
		if(isset($cron[$hook])) return $timestamp;
	}
	return false;
}

function spawn_cron() {
	if (array_shift(array_keys(get_option('cron'))) > time()) return;

	$cron_url = get_settings('siteurl') . '/wp-cron.php';
	$parts = parse_url($cron_url);
	$argyle = @ fsockopen($parts['host'], $_SERVER['SERVER_PORT'], $errno, 
$errstr, 0.01);
	if ( $argyle )
		fputs($argyle, "GET {$parts['path']}?time=" . time() . '&check='
		. md5(DB_PASS . '187425') . " HTTP/1.0\r\nHost: 
{$_SERVER['HTTP_HOST']}\r\n\r\n");
}

function wp_cron() {
	if (array_shift(array_keys(get_option('cron'))) > time())
		return;

	$crons = get_option('cron');
	$newcrons = $crons;
	foreach ($crons as $timestamp => $cronhooks) {
		if ($timestamp > time()) break;
		foreach($cronhooks as $hook => $args) {
			do_action($hook, $args['args']);
			$recurrence = $args['recur'];
			if ( 'hourly' == $recurrence )
				wp_schedule_event($timestamp + 3600, $recurrence, $hook, $args['args']);
			else if ( 'daily' == $recurrence )
				wp_schedule_event($timestamp + 86400, $recurrence, $hook, 
$args['args']);

			wp_unschedule_event($timestamp, $hook);
		}
	}
}

wp-cron.php looks like:

<?php
require_once('./wp-config.php');

if ( $_GET['check'] != md5(DB_PASS . '187425') )
	exit;

wp_cron();

?>

spawn_cron() causes some mischief on my server. Pages are slow to load 
and apache2 sometimes bumps to 100% CPU until I kill it.  So, I'm just 
calling wp_cron() from the shutdown hook for now.

Here's a sample plugin implementation:

add_action('test_cron', 'test_cron', 10, 2);

function test_cron($arg1, $arg2) {
         syslog(LOG_ERR, "Arg 1 is $arg1 and arg2 is $arg2");
}

if ( ! next_scheduled('test_cron') )
         wp_schedule_event(time(), 'hourly', 'test_cron', "hello", "world");


More information about the wp-hackers mailing list