[wp-hackers] WP cron and "multi-threading"

Robert Deaton false.hopes at gmail.com
Sun Oct 8 22:50:28 GMT 2006


On 10/8/06, Owen Winkler <ringmaster at midnightcircus.com> wrote:
> I've used wp_schedule_event() to register a cron event during the
> activation of my plugin, and I have a couple of issues.
>
> #1: The cron event seems to leave remnants of non-existent args in the
> serialized options array.  Every time it runs it adds an array wrapper
> to the existing zero-length array of arguments.  I don't know if this
> patch (http://trac.wordpress.org/ticket/3169) will fix it.  I'm not sure
> if it's causing any issues with the plugin itself since I'm not using
> the parameters, but I don't think it will be a problem, at least until
> the size of the data exceeds the field length.
>
> #2: I need the cron to run *exactly once* at each interval.  Assuming
> that traffic on the site is buzzing along, the current cron
> implementation could allow events to be processed more than once,
> depending on how long it takes for the hooked function to run.  In my
> case, the computation in the cron hook usually takes 2 seconds or more,
> leaving plenty of room for another incoming hit to trigger the same event.
>
> I've implemented a flock() check in my own code, something I'd rather
> not do.  It might be beneficial to rearrange the cron code so that it
> unschedules the event before it executes it.
>
> Any other clever suggestions as to how to keep the cron from executing
> more than once on a single registered instance would be helpful.

I've run into this before in testing and I've thought a lot about the
best way to handle the race condition. The best I can think of, and I
think it may work, is in wp-cron.php, we set an option that says "we
are busy doing the cron" along with some random hash. Then we sleep
for 500 usecs, and check the value of the option. If the option has
the same value, we continue. If the option has a different value,
there was some race condition, and the other thread run, and we die.
Psuedo-code:

if(get_option('cron_is_running'))
    die(); // Something else definitely beat us to it.
$localhash = generate_some_random_hashval(); // Possibly based on
microtime, as there is no way with current computing power that we'd
generate a hash twice in the same usec.
update_option('cron_is_running', 'something with the hashval to tell
us its true');
usleep(250000); // Sleep for 1/4th of a second
if(get_option('cron_is_running') && $hash_from_that_option != $localhash)
     die(); // Something else had a race condition with us and won, we die();

-- 
--Robert Deaton


More information about the wp-hackers mailing list