WordPress.org

Make WordPress Core

Ticket #17462: 17462.3.diff

File 17462.3.diff, 5.4 KB (added by ryan, 3 years ago)
  • 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

     
    208208 * 
    209209 * @since 2.6.0 
    210210 */ 
    211 function wp_cache_reset() { 
     211function wp_cache_reset( $group = '', $key = '' ) { 
    212212        global $wp_object_cache; 
    213213 
    214         return $wp_object_cache->reset(); 
     214        return $wp_object_cache->reset( $group, $key ); 
    215215} 
    216216 
    217217/** 
     
    480480         * 
    481481         * @since 3.0.0 
    482482         */ 
    483         function reset() { 
    484                 // Clear out non-global caches since the blog ID has changed. 
    485                 foreach ( array_keys($this->cache) as $group ) { 
    486                         if ( !in_array($group, $this->global_groups) ) 
    487                                 unset($this->cache[$group]); 
     483        function reset( $group = '', $id = '' ) { 
     484                if ( ! empty( $group ) ) { 
     485                        if ( !empty( $id ) ) { 
     486                                // Clear out a particular key 
     487                                if ( isset( $this->cache[$group][$id] ) ) 
     488                                        unset( $this->cache[$group][$id] ); 
     489                        } else { 
     490                                // Clear out a particular group 
     491                                if ( isset( $this->cache[$group] ) ) 
     492                                        unset( $this->cache[$group] ); 
     493                        } 
     494                } else { 
     495                        // Clear out non-global caches since the blog ID has changed. 
     496                        foreach ( array_keys($this->cache) as $group ) { 
     497                                if ( !in_array($group, $this->global_groups) ) 
     498                                        unset($this->cache[$group]); 
     499                        } 
    488500                } 
    489501        } 
    490502 
  • 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 
     
    227227                        return; 
    228228 
    229229                set_transient( 'doing_cron', $local_time ); 
     230                $lock = $local_time; 
    230231 
    231232                ob_start(); 
    232233                wp_redirect( add_query_arg('doing_wp_cron', '', stripslashes($_SERVER['REQUEST_URI'])) ); 
     
    241242        } 
    242243 
    243244        set_transient( 'doing_cron', $local_time ); 
     245        $lock = $local_time; 
    244246 
    245         $cron_url = get_option( 'siteurl' ) . '/wp-cron.php?doing_wp_cron'; 
     247        $cron_url = get_option( 'siteurl' ) . '/wp-cron.php?lock=' . $lock; 
    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                // Clear the internal cache for the doing_cron transient to force a cache refresh 
     36                if ( function_exists( 'wp_cache_reset' ) ) 
     37                        wp_cache_reset( 'transient', 'doing_cron' ); 
     38                $value = wp_cache_get( $transient, 'transient' ); 
     39        } else { 
     40                $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) ); 
     41                if ( is_object( $row ) ) 
     42                        $value = $row->option_value; 
     43        } 
     44 
     45        return $value; 
     46} 
     47 
    2948if ( false === $crons = _get_cron_array() ) 
    3049        die(); 
    3150 
     
    3554if ( isset($keys[0]) && $keys[0] > $local_time ) 
    3655        die(); 
    3756 
    38 foreach ($crons as $timestamp => $cronhooks) { 
     57$doing_cron = get_transient( 'doing_cron'); 
     58 
     59// Use global $lock otherwise GET lock. If no lock, trying grabbing a new lock. 
     60if ( empty( $lock ) ) { 
     61        if ( empty( $_GET[ 'lock' ] ) ) { 
     62                // Called from external script/job. Try setting a lock. 
     63                if ( $doing_cron && ( $doing_cron + WP_CRON_LOCK_TIMEOUT > $local_time ) ) 
     64                        return; 
     65                $doing_cron = $lock = time(); 
     66                set_transient( 'doing_cron', $lock ); 
     67        } else { 
     68                $lock = $_GET[ 'lock' ]; 
     69        } 
     70} 
     71 
     72// Check lock 
     73if ( $doing_cron != $lock ) 
     74        return; 
     75 
     76foreach ( $crons as $timestamp => $cronhooks ) { 
    3977        if ( $timestamp > $local_time ) 
    4078                break; 
    4179 
    42         foreach ($cronhooks as $hook => $keys) { 
     80        foreach ( $cronhooks as $hook => $keys ) { 
    4381 
    44                 foreach ($keys as $k => $v) { 
     82                foreach ( $keys as $k => $v ) { 
    4583 
    4684                        $schedule = $v['schedule']; 
    4785 
    48                         if ($schedule != false) { 
     86                        if ( $schedule != false ) { 
    4987                                $new_args = array($timestamp, $schedule, $hook, $v['args']); 
    5088                                call_user_func_array('wp_reschedule_event', $new_args); 
    5189                        } 
    5290 
    53                         wp_unschedule_event($timestamp, $hook, $v['args']); 
     91                        wp_unschedule_event( $timestamp, $hook, $v['args'] ); 
    5492 
    55                         do_action_ref_array($hook, $v['args']); 
     93                        do_action_ref_array( $hook, $v['args'] ); 
     94 
     95                        // If the hook ran too long and another cron process stole the lock, quit. 
     96                        if ( _get_cron_lock() != $lock ) 
     97                                return; 
    5698                } 
    5799        } 
    58100} 
    59101 
     102if ( _get_cron_lock() == $lock ) 
     103        delete_transient( 'doing_cron' ); 
     104 
    60105die();