WordPress.org

Make WordPress Core

Ticket #17462: 17462.6.diff

File 17462.6.diff, 5.9 KB (added by ryan, 3 years ago)

Use doing_wp_cron instead of lock

  • wp-includes/default-constants.php

     
    268268 
    269269        if ( !defined('WP_POST_REVISIONS') ) 
    270270                define('WP_POST_REVISIONS', true); 
     271 
     272        /** 
     273         * @since 3.3.0 
     274         */ 
     275        if ( !defined( 'WP_CRON_LOCK_TIMEOUT' ) ) 
     276                define('WP_CRON_LOCK_TIMEOUT', 60);  // In seconds 
    271277} 
    272278 
    273279/** 
  • wp-includes/cache.php

     
    102102 * 
    103103 * @param int|string $key What the contents in the cache are called 
    104104 * @param string $group Where the cache contents are grouped 
     105 * @param bool $force Whether to force an update of the local cache from the persistent cache (default is false) 
    105106 * @return bool|mixed False on failure to retrieve contents or the cache 
    106107 *              contents on success 
    107108 */ 
    108 function wp_cache_get($key, $group = '') { 
     109function wp_cache_get( $key, $group = '', $force = false ) { 
    109110        global $wp_object_cache; 
    110111 
    111         return $wp_object_cache->get($key, $group); 
     112        return $wp_object_cache->get( $key, $group, $force ); 
    112113} 
    113114 
    114115/** 
     
    403404         * 
    404405         * @param int|string $key What the contents in the cache are called 
    405406         * @param string $group Where the cache contents are grouped 
     407         * @param string $force Whether to force a refetch rather than relying on the local cache (default is false) 
    406408         * @return bool|mixed False on failure to retrieve contents or the cache 
    407409         *              contents on success 
    408410         */ 
    409         function get($key, $group = 'default') { 
     411        function get( $key, $group = 'default', $force = false) { 
    410412                if ( empty ($group) ) 
    411413                        $group = 'default'; 
    412414 
  • wp-includes/cron.php

     
    204204        * multiple processes on multiple web servers can run this code concurrently 
    205205        * try to make this as atomic as possible by setting doing_cron switch 
    206206        */ 
    207         $flag = get_transient('doing_cron'); 
     207        $lock = get_transient('doing_cron'); 
    208208 
    209         if ( $flag > $local_time + 10*60 ) 
    210                 $flag = 0; 
     209        if ( $lock > $local_time + 10*60 ) 
     210                $lock = 0; 
    211211 
    212212        // don't run if another process is currently running it or more than once every 60 sec. 
    213         if ( $flag + 60 > $local_time ) 
     213        if ( $lock + WP_CRON_LOCK_TIMEOUT > $local_time ) 
    214214                return; 
    215215 
    216216        //sanity check 
     
    226226                if ( !empty($_POST) || defined('DOING_AJAX') ) 
    227227                        return; 
    228228 
    229                 set_transient( 'doing_cron', $local_time ); 
     229                $doing_wp_cron = $local_time; 
     230                set_transient( 'doing_cron', $doing_wp_cron ); 
    230231 
    231232                ob_start(); 
    232                 wp_redirect( add_query_arg('doing_wp_cron', '', stripslashes($_SERVER['REQUEST_URI'])) ); 
     233                wp_redirect( add_query_arg('doing_wp_cron', $doing_wp_cron, stripslashes($_SERVER['REQUEST_URI'])) ); 
    233234                echo ' '; 
    234235 
    235236                // flush any buffers and send the headers 
     
    240241                return; 
    241242        } 
    242243 
    243         set_transient( 'doing_cron', $local_time ); 
     244        $doing_wp_cron = $local_time; 
     245        set_transient( 'doing_cron', $doing_wp_cron ); 
    244246 
    245         $cron_url = get_option( 'siteurl' ) . '/wp-cron.php?doing_wp_cron'; 
     247        $cron_url = get_option( 'siteurl' ) . '/wp-cron.php?doing_wp_cron=' . $doing_wp_cron; 
    246248        wp_remote_post( $cron_url, array('timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters('https_local_ssl_verify', true)) ); 
    247249} 
    248250 
  • wp-cron.php

     
    2626        require_once('./wp-load.php'); 
    2727} 
    2828 
     29// Uncached doing_cron transient fetch 
     30function _get_cron_lock() { 
     31        global $_wp_using_ext_object_cache, $wpdb; 
     32 
     33        $value = 0; 
     34        if ( $_wp_using_ext_object_cache ) { 
     35                // Skip local cache and force refetch of doing_cron transient in case 
     36                // another processs updated the cache 
     37                $value = wp_cache_get( 'doing_cron', 'transient', true ); 
     38        } else { 
     39                $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) ); 
     40                if ( is_object( $row ) ) 
     41                        $value = $row->option_value; 
     42        } 
     43 
     44        return $value; 
     45} 
     46 
    2947if ( false === $crons = _get_cron_array() ) 
    3048        die(); 
    3149 
     
    3553if ( isset($keys[0]) && $keys[0] > $local_time ) 
    3654        die(); 
    3755 
    38 foreach ($crons as $timestamp => $cronhooks) { 
     56$doing_cron_transient = get_transient( 'doing_cron'); 
     57 
     58// Use global $doing_wp_cron lock otherwise use the GET lock. If no lock, trying grabbing a new lock. 
     59if ( empty( $doing_wp_cron ) ) { 
     60        if ( empty( $_GET[ 'doing_wp_cron' ] ) ) { 
     61                // Called from external script/job. Try setting a lock. 
     62                if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $local_time ) ) 
     63                        return; 
     64                $doing_cron_transient = $doing_wp_cron = time(); 
     65                set_transient( 'doing_cron', $doing_wp_cron ); 
     66        } else { 
     67                $doing_wp_cron = $_GET[ 'doing_wp_cron' ]; 
     68        } 
     69} 
     70 
     71// Check lock 
     72if ( $doing_cron_transient != $doing_wp_cron ) 
     73        return; 
     74 
     75foreach ( $crons as $timestamp => $cronhooks ) { 
    3976        if ( $timestamp > $local_time ) 
    4077                break; 
    4178 
    42         foreach ($cronhooks as $hook => $keys) { 
     79        foreach ( $cronhooks as $hook => $keys ) { 
    4380 
    44                 foreach ($keys as $k => $v) { 
     81                foreach ( $keys as $k => $v ) { 
    4582 
    4683                        $schedule = $v['schedule']; 
    4784 
    48                         if ($schedule != false) { 
     85                        if ( $schedule != false ) { 
    4986                                $new_args = array($timestamp, $schedule, $hook, $v['args']); 
    5087                                call_user_func_array('wp_reschedule_event', $new_args); 
    5188                        } 
    5289 
    53                         wp_unschedule_event($timestamp, $hook, $v['args']); 
     90                        wp_unschedule_event( $timestamp, $hook, $v['args'] ); 
    5491 
    55                         do_action_ref_array($hook, $v['args']); 
     92                        do_action_ref_array( $hook, $v['args'] ); 
     93 
     94                        // If the hook ran too long and another cron process stole the lock, quit. 
     95                        if ( _get_cron_lock() != $doing_wp_cron ) 
     96                                return; 
    5697                } 
    5798        } 
    5899} 
    59100 
     101if ( _get_cron_lock() == $doing_wp_cron ) 
     102        delete_transient( 'doing_cron' ); 
     103 
    60104die();