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

Owen Winkler ringmaster at midnightcircus.com
Fri Feb 10 16:17:03 GMT 2006


Ryan Boren wrote:
> Jeff Minard wrote:
>> May I suggest we take a page from "The History of Every Unix Ever" and 
>> at least make the psuedo cron scheduler something that people can 
>> learn just once?
>>
>> wp_schedule_repeating_event($minute, $hour, $dayofmonth, $month, 
>> $dayofweek, $filter_to_activate);
>>
>> The whole "* * * * *" thing.
> 
> Hah!  I'm with you there.  Even after over a decade of dealing with 
> crontab files I still have to scratch my head and look at man pages 
> whenever I edit one.

This is funny.

Ryan has assumed that the message is sarcastic; scheduling cron is 
something he has to look up every time (me too!), and so should be made 
simpler.

Skippy (in forked thread) has assumed that Jeff really meant to leverage 
years of unix documentation to implement a wp_cron format that would be 
familiar to unix users.  (And what is the crossover between unix admin 
and PHP knowledge, I wonder?)

Personally, if I never have to look up how to do things like "Every 20 
minutes on Saturday" in the cron man again, I'll be happier for it.

My vote - Forget the unix cron crap and make this simple:


function wp_schedule_event($timestamp, $hook)
{
	$args = array_slice(func_get_args(), 2);
	$crons = get_option('cron');
	$crons[$timestamp][$hook] = $args;
	ksort($crons);
	update_option('cron', $crons);
}

function wp_unschedule_event($timestamp, $hook)
{
	$crons = get_option('cron');
	unset($crons[$timestamp][$hook]);
	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');
	foreach($crons as $timestamp => $cron) {
		if($timestamp <= time()) continue;
		if(isset($cron[$hook])) return $timestamp;
	}
	return false;
}

function spawn_crons()
// Executed frequently/periodically on page loads
{
	if (array_shift(array_keys(get_option('cron')) > time()) return;

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

}

... Then in execute-cron.php ...

require_once('../wp-config.php');
if (array_shift(array_keys(get_option('cron')) > time()) exit;
$crons = get_option('cron');
$newcrons = $crons;
foreach ($crons as $timestamp => $cronhooks) {
	if ($timestamp > time()) break;
	foreach($cronhooks as $hook => $args) {
		do_action($hook, $args);
	}
	unset($newcrons[$timestamp]);
}
update_option('cron', $newcrons);


Adding a new 20-minute repeating event would look like:

wp_schedule_event(time(), 'every_20_minutes', 0);
add_action('every_20_minutes', 'fn_every_20_minutes');
function fn_every_20_minutes($execount)
{
	// Do stuff.
	if (next_scheduled('every_20_minutes') !== false)
	wp_schedule_event(strtotime('+20 minutes'), 'every_20_minutes', 
$execount++);
}


Or something.  (None of the above code has been shown to a parser.)

Owen



More information about the wp-hackers mailing list