Make WordPress Core

Opened 7 months ago

Last modified 5 months ago

#63830 new defect (bug)

Event system breaks when an event is scheduled during processing of a queue of more than one events

Reported by: madhazelnut's profile madhazelnut Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.8.2
Component: Cron API Keywords: has-patch
Focuses: Cc:

Description

We've had instances of events "disappearing" and traced it down to them not being registered in the event system when a queue of more than one event is being processed in parallel.

To Reproduce

Step 1

Add the following code (in a must-use plugin, for example):

<?php
add_action('my_regular_task', function($param) {
    // do something meaningful
});

add_action('my_long_task', function() {
    echo 'Started my_long_task. Maybe request an HTTP page now?', "\n";
    for($i=0;$i<5; $i++) {
        sleep(2);
        echo "\t", 'Zzz..', "\n";
    }
    echo 'Woa. Woke up!', "\n";
});

add_action('init', function() {
    if (!defined('WP_CLI')) {
        // This runs when requested via HTTP
        $evt = wp_schedule_single_event(time()+1 , 'my_regular_task', [uniqid()], true);
        if (is_wp_error($evt)) {
            die('Could not schedule event!');   // this makes sure the event was indeed registered as scheduled..
        }
    }
});

Step 2

In a WPCLI session:

wp cron event schedule my_long_task --0=foo
wp cron event schedule my_long_task --0=bar
wp cron event run --due-now

While the two events are being processed perform one HTTP request to any front end page in your browser (to schedule the regular task).

Step 3

wp cron event list

Expected result

On step 3 we see the list of events containing one instance of my_regular_task.

Actual result

The event list does NOT contain my_regular_task.

Change History (5)

#1 @madhazelnut
7 months ago

The cause is in the _get_cron_array function, which retrieves the cron via a regular get_option call, which, in turn, retrieves a cached version of the cron. A cached version of the cron is not going to contain an event added *after* the caching occurred, which is exactly what's happening here.

The solution would involve retrieving an uncached version of the cron option, when performing the unscheduling.

This ticket was mentioned in PR #9496 on WordPress/wordpress-develop by slavicd.


7 months ago
#2

  • Keywords has-patch added

Allows requesting a fresh cron array when unscheduling a job.

Trac ticket: https://core.trac.wordpress.org/ticket/63830

This ticket was mentioned in PR #9517 on WordPress/wordpress-develop by slavicd.


7 months ago
#3

Cron events system breaks by ignoring events added *during* processing of an event queue.

Trac ticket: https://core.trac.wordpress.org/ticket/63830

@peterwilsoncc commented on PR #9517:


7 months ago
#4

Closing this off to avoid confusion as it's a duplicate of https://github.com/WordPress/wordpress-develop/pull/9496

This ticket was mentioned in Slack in #core by madhazelnut. View the logs.


5 months ago

Note: See TracTickets for help on using tickets.