Make WordPress Core

Opened 6 years ago

Closed 6 years ago

Last modified 3 years ago

#39924 closed defect (bug) (duplicate)

wp_schedule_single_event is possibly failed to schedule a task when it is called concurrently

Reported by: hainey's profile hainey Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Cron API Keywords:
Focuses: Cc:

Description

In some occaltionally case, we found the wp_schedule_single_event was called, but the event did not happen.

At last we find the possible reason is in wp_schedule_single_event function

$crons = _get_cron_array();

...
$crons[$event->timestamp][$event->hook][$key] = ...

_set_cron_array( $crons );

If we have two threads calling wp_schedule_single_event at the same time, it could be possible only one cron event is overwritten by another thread.

Change History (2)

#1 @dd32
6 years ago

  • Component changed from General to Cron API
  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed
  • Version 4.6 deleted

Hi @hainey and welcome to Trac,

Unfortunately race conditions such as this are a well known (amongst some) issue with WordPress's cron system - It's not designed to be used in a scenario where it's likely events are to be registered in such a way that a race condition could be hit.

This is a duplicate of #13158, however you may also be interested in #15148. There exist alternative storage options for WordPress cron events though, one such option that I use (and WordPress.org also uses) is Cavalcade - a separate daemon which runs on the server on top of wp-cli and guarantees (more or less) that jobs get scheduled and run.

#2 @archon810
3 years ago

On busy sites, like ours, schedule_single_event() is borderline useless and extremely unreliable due to the race condition and WP's continued use of a single array for wpcron.

It has resulted in entire sites being brought down when the cron array grows in size for whatever reason and the constant reading and writing/overwriting brings down databases.

A simple solution that I'm shocked WP maintainers haven't implemented yet would be to move wpcron to its own table, which can then be properly interacted with on a row-by-row event-by-event basis. Setting up Cavalcade shouldn't be necessary to resolve events getting dropped, resulting in missed schedules.

Why is wp cron still not its own table? Imagine if postmeta was a serialized field in wp_posts.

I filed https://core.trac.wordpress.org/ticket/49520 because I strongly think WP cron should be resolved properly once and for all.

Last edited 3 years ago by archon810 (previous) (diff)
Note: See TracTickets for help on using tickets.