Make WordPress Core

Opened 14 months ago

Last modified 13 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 Owned by:
Priority: normal Milestone: Awaiting Review
Component: Cron API Version: 6.8.2
Severity: normal Keywords: has-patch
Cc: Focuses:

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
14 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.


14 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.


14 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:


14 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.


13 months ago

Note: See TracTickets for help on using tickets.