Plugin Directory

Changeset 2571100


Ignore:
Timestamp:
07/23/2021 07:11:29 PM (4 years ago)
Author:
andy
Message:

memcached version 4.0.0

Location:
memcached
Files:
1 deleted
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • memcached/tags/4.0.0/object-cache.php

    r2317338 r2571100  
    44Plugin Name: Memcached
    55Description: Memcached backend for the WP Object Cache.
    6 Version: 3.2.2
    7 Plugin URI: http://wordpress.org/extend/plugins/memcached/
     6Version: 4.0.0
     7Plugin URI: https://wordpress.org/plugins/memcached/
    88Author: Ryan Boren, Denis de Bernardy, Matt Martz, Andy Skelton
    99
     
    5555function wp_cache_get( $key, $group = '', $force = false, &$found = null ) {
    5656    global $wp_object_cache;
     57
     58    $value = apply_filters( 'pre_wp_cache_get', false, $key, $group, $force );
     59    if ( false !== $value ) {
     60        $found = true;
     61        return $value;
     62    }
    5763
    5864    return $wp_object_cache->get( $key, $group, $force, $found );
     
    116122    var $no_mc_groups = array();
    117123
    118     var $cache     = array();
    119     var $mc        = array();
    120     var $stats     = array();
    121     var $group_ops = array();
    122 
     124    var $cache       = array();
     125    var $mc          = array();
     126    var $default_mcs = array();
     127    var $stats       = array();
     128    var $group_ops   = array();
     129
     130    var $flush_group         = 'WP_Object_Cache';
     131    var $global_flush_group  = 'WP_Object_Cache_global';
     132    var $flush_key           = "flush_number_v4";
     133    var $old_flush_key       = "flush_number";
    123134    var $flush_number        = array();
    124135    var $global_flush_number = null;
     
    268279    }
    269280
     281    // Gets number from all default servers, replicating if needed
     282    function get_max_flush_number( $group ) {
     283        $key = $this->key( $this->flush_key, $group );
     284
     285        $values = array();
     286        $size = 19; // size of microsecond timestamp serialized
     287        foreach ( $this->default_mcs as $i => $mc ) {
     288            $flags = false;
     289            $this->timer_start();
     290            $values[ $i ] = $mc->get( $key, $flags );
     291            $elapsed = $this->timer_stop();
     292
     293            if ( empty( $values[ $i ] ) ) {
     294                $this->group_ops_stats( 'get_flush_number', $key, $group, null, $elapsed, 'not_in_memcache' );
     295            } else {
     296                $this->group_ops_stats( 'get_flush_number', $key, $group, $size, $elapsed, 'memcache' );
     297            }
     298        }
     299
     300        $max = max( $values );
     301
     302        if ( ! $max > 0 ) {
     303            return false;
     304        }
     305
     306        // Replicate to servers not having the max.
     307        $expire = 0;
     308        foreach ( $this->default_mcs as $i => $mc ) {
     309            if ( $values[ $i ] < $max ) {
     310                $this->timer_start();
     311                $mc->set( $key, $max, false, $expire );
     312                $elapsed = $this->timer_stop();
     313                $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication_repair' );
     314            }
     315        }
     316
     317        return $max;
     318    }
     319
     320    function set_flush_number( $value, $group ) {
     321        $key = $this->key( $this->flush_key, $group );
     322        $expire = 0;
     323        $size = 19;
     324        foreach ( $this->default_mcs as $i => $mc ) {
     325            $this->timer_start();
     326            $mc->set( $key, $value, false, $expire );
     327            $elapsed = $this->timer_stop();
     328            $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication' );
     329        }
     330    }
     331
     332    function get_flush_number( $group ) {
     333        $flush_number = $this->get_max_flush_number( $group );
     334        // What if there is no v4 flush number?
     335        if ( empty( $flush_number ) ) {
     336            // Look for the v3 flush number key.
     337            $flush_number = intval( $this->get( $this->old_flush_key, $group ) );
     338            if ( !empty( $flush_number ) ) {
     339                // Found v3 flush number. Upgrade to v4 with replication.
     340                $this->set_flush_number( $flush_number, $group );
     341                // Delete v3 key so we can't later restore it and find stale keys.
     342            } else {
     343                // No flush number found anywhere. Make a new one. This flushes the cache.
     344                $flush_number = $this->new_flush_number();
     345                $this->set_flush_number( $flush_number, $group );
     346            }
     347        }
     348
     349        return $flush_number;
     350    }
     351
     352    function get_global_flush_number() {
     353        if ( ! isset( $this->global_flush_number ) ) {
     354            $this->global_flush_number = $this->get_flush_number( $this->global_flush_group );
     355        }
     356        return $this->global_flush_number;
     357    }
     358
     359    function get_blog_flush_number() {
     360        if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) {
     361            $this->flush_number[ $this->blog_prefix ] = $this->get_flush_number( $this->flush_group );
     362        }
     363        return $this->flush_number[ $this->blog_prefix ];
     364    }
     365
    270366    function flush() {
    271367        // Do not use the memcached flush method. It acts on an
     
    273369        // Flush is also unusable in some setups, e.g. twemproxy.
    274370        // Instead, rotate the key prefix for the current site.
    275         // Global keys are rotated when flushing on the main site.
     371        // Global keys are rotated when flushing on any network's
     372        // main site.
    276373        $this->cache = array();
    277374
    278         $this->rotate_site_keys();
     375        $flush_number = $this->new_flush_number();
     376
     377        $this->rotate_site_keys( $flush_number );
    279378
    280379        if ( is_main_site() ) {
    281             $this->rotate_global_keys();
    282         }
    283     }
    284 
    285     function rotate_site_keys() {
    286         $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache' );
    287 
    288         $this->flush_number[ $this->blog_prefix ] = $this->incr( 'flush_number', 1, 'WP_Object_Cache' );
    289     }
    290 
    291     function rotate_global_keys() {
    292         $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache_global' );
    293 
    294         $this->global_flush_number = $this->incr( 'flush_number', 1, 'WP_Object_Cache_global' );
     380            $this->rotate_global_keys( $flush_number );
     381        }
     382    }
     383
     384    function rotate_site_keys( $flush_number = null ) {
     385        if ( is_null( $flush_number ) ) {
     386            $flush_number = $this->new_flush_number();
     387        }
     388
     389        $this->set_flush_number( $flush_number, $this->flush_group );
     390
     391        $this->flush_number[ $this->blog_prefix ] = $flush_number;
     392    }
     393
     394    function rotate_global_keys( $flush_number = null ) {
     395        if ( is_null( $flush_number ) ) {
     396            $flush_number = $this->new_flush_number();
     397        }
     398
     399        $this->set_flush_number( $flush_number, $this->global_flush_group );
     400
     401        $this->global_flush_number = $flush_number;
     402    }
     403
     404    function new_flush_number() {
     405        return intval( microtime( true ) * 1e6 );
    295406    }
    296407
     
    418529
    419530    function flush_prefix( $group ) {
    420         if ( 'WP_Object_Cache' === $group || 'WP_Object_Cache_global' === $group ) {
     531        if ( $group === $this->flush_group || $group === $this->global_flush_group ) {
    421532            // Never flush the flush numbers.
    422533            $number = '_';
    423534        } elseif ( false !== array_search( $group, $this->global_groups ) ) {
    424             if ( ! isset( $this->global_flush_number ) ) {
    425                 $this->global_flush_number = intval( $this->get( 'flush_number', 'WP_Object_Cache_global' ) );
    426             }
    427 
    428             if ( 0 === $this->global_flush_number ) {
    429                 $this->rotate_global_keys();
    430             }
    431 
    432             $number = $this->global_flush_number;
     535            $number = $this->get_global_flush_number();
    433536        } else {
    434             if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) {
    435                 $this->flush_number[ $this->blog_prefix ] = intval( $this->get( 'flush_number', 'WP_Object_Cache' ) );
    436             }
    437 
    438             if ( 0 === $this->flush_number[ $this->blog_prefix ] ) {
    439                 $this->rotate_site_keys();
    440             }
    441 
    442             $number = $this->flush_number[ $this->blog_prefix ];
    443         }
    444 
     537            $number = $this->get_blog_flush_number();
     538        }
    445539        return $number . ':';
    446540    }
     
    616710        }
    617711
    618         echo "<ul class='debug-menu-links'>\n";
     712        echo "<ul class='debug-menu-links' style='clear:left;font-size:14px;'>\n";
    619713        $groups = array_keys( $this->group_ops );
    620714        usort( $groups, 'strnatcasecmp' );
     
    755849            $this->mc[ $bucket ] = new Memcache();
    756850
    757             foreach ( $servers as $server  ) {
     851            foreach ( $servers as $i => $server  ) {
    758852                if ( 'unix://' == substr( $server, 0, 7 ) ) {
    759853                    $node = $server;
     
    775869                $this->mc[ $bucket ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) );
    776870                $this->mc[ $bucket ]->setCompressThreshold( 20000, 0.2 );
     871
     872                // Prepare individual connections to servers in default bucket for flush_number redundancy
     873                if ( 'default' === $bucket ) {
     874                    $this->default_mcs[ $i ] = new Memcache();
     875                    $this->default_mcs[ $i ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) );
     876                }
    777877            }
    778878        }
     
    827927
    828928    /**
    829      * Key format: key_salt:flush_timer:table_prefix:key_name
     929     * Key format: key_salt:flush_number:table_prefix:key_name
    830930     *
    831      * We want to strip the `key_salt:flush_timer` part to not leak the memcached keys.
    832      * If `key_salt` is set we strip `'key_salt:flush_timer`, otherwise just strip the `flush_timer` part.
     931     * We want to strip the `key_salt:flush_number` part to not leak the memcached keys.
     932     * If `key_salt` is set we strip `'key_salt:flush_number`, otherwise just strip the `flush_number` part.
    833933     */
    834934    function strip_memcached_keys( $keys ) {
  • memcached/tags/4.0.0/readme.txt

    r2317344 r2571100  
    33Tags: cache, memcached
    44Requires at least: 5.3
    5 Tested up to: 5.4.1
    6 Stable tag: 3.2.2
     5Tested up to: 5.8
     6Stable tag: 4.0.0
    77Requires PHP: 5.6.20
    88
     
    8484== Changelog ==
    8585
     86= 4.0.0 =
     87* Add preemptive filter pre_wp_cache_get
     88* Add flush_number replication to prevent accidental flush due to flush_number eviction, server rotation, etc.
     89
    8690= 3.2.2 =
    8791* Remove filter, and base key stripping on presence of `key_salt`
  • memcached/trunk/object-cache.php

    r2317338 r2571100  
    44Plugin Name: Memcached
    55Description: Memcached backend for the WP Object Cache.
    6 Version: 3.2.2
    7 Plugin URI: http://wordpress.org/extend/plugins/memcached/
     6Version: 4.0.0
     7Plugin URI: https://wordpress.org/plugins/memcached/
    88Author: Ryan Boren, Denis de Bernardy, Matt Martz, Andy Skelton
    99
     
    5555function wp_cache_get( $key, $group = '', $force = false, &$found = null ) {
    5656    global $wp_object_cache;
     57
     58    $value = apply_filters( 'pre_wp_cache_get', false, $key, $group, $force );
     59    if ( false !== $value ) {
     60        $found = true;
     61        return $value;
     62    }
    5763
    5864    return $wp_object_cache->get( $key, $group, $force, $found );
     
    116122    var $no_mc_groups = array();
    117123
    118     var $cache     = array();
    119     var $mc        = array();
    120     var $stats     = array();
    121     var $group_ops = array();
    122 
     124    var $cache       = array();
     125    var $mc          = array();
     126    var $default_mcs = array();
     127    var $stats       = array();
     128    var $group_ops   = array();
     129
     130    var $flush_group         = 'WP_Object_Cache';
     131    var $global_flush_group  = 'WP_Object_Cache_global';
     132    var $flush_key           = "flush_number_v4";
     133    var $old_flush_key       = "flush_number";
    123134    var $flush_number        = array();
    124135    var $global_flush_number = null;
     
    268279    }
    269280
     281    // Gets number from all default servers, replicating if needed
     282    function get_max_flush_number( $group ) {
     283        $key = $this->key( $this->flush_key, $group );
     284
     285        $values = array();
     286        $size = 19; // size of microsecond timestamp serialized
     287        foreach ( $this->default_mcs as $i => $mc ) {
     288            $flags = false;
     289            $this->timer_start();
     290            $values[ $i ] = $mc->get( $key, $flags );
     291            $elapsed = $this->timer_stop();
     292
     293            if ( empty( $values[ $i ] ) ) {
     294                $this->group_ops_stats( 'get_flush_number', $key, $group, null, $elapsed, 'not_in_memcache' );
     295            } else {
     296                $this->group_ops_stats( 'get_flush_number', $key, $group, $size, $elapsed, 'memcache' );
     297            }
     298        }
     299
     300        $max = max( $values );
     301
     302        if ( ! $max > 0 ) {
     303            return false;
     304        }
     305
     306        // Replicate to servers not having the max.
     307        $expire = 0;
     308        foreach ( $this->default_mcs as $i => $mc ) {
     309            if ( $values[ $i ] < $max ) {
     310                $this->timer_start();
     311                $mc->set( $key, $max, false, $expire );
     312                $elapsed = $this->timer_stop();
     313                $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication_repair' );
     314            }
     315        }
     316
     317        return $max;
     318    }
     319
     320    function set_flush_number( $value, $group ) {
     321        $key = $this->key( $this->flush_key, $group );
     322        $expire = 0;
     323        $size = 19;
     324        foreach ( $this->default_mcs as $i => $mc ) {
     325            $this->timer_start();
     326            $mc->set( $key, $value, false, $expire );
     327            $elapsed = $this->timer_stop();
     328            $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication' );
     329        }
     330    }
     331
     332    function get_flush_number( $group ) {
     333        $flush_number = $this->get_max_flush_number( $group );
     334        // What if there is no v4 flush number?
     335        if ( empty( $flush_number ) ) {
     336            // Look for the v3 flush number key.
     337            $flush_number = intval( $this->get( $this->old_flush_key, $group ) );
     338            if ( !empty( $flush_number ) ) {
     339                // Found v3 flush number. Upgrade to v4 with replication.
     340                $this->set_flush_number( $flush_number, $group );
     341                // Delete v3 key so we can't later restore it and find stale keys.
     342            } else {
     343                // No flush number found anywhere. Make a new one. This flushes the cache.
     344                $flush_number = $this->new_flush_number();
     345                $this->set_flush_number( $flush_number, $group );
     346            }
     347        }
     348
     349        return $flush_number;
     350    }
     351
     352    function get_global_flush_number() {
     353        if ( ! isset( $this->global_flush_number ) ) {
     354            $this->global_flush_number = $this->get_flush_number( $this->global_flush_group );
     355        }
     356        return $this->global_flush_number;
     357    }
     358
     359    function get_blog_flush_number() {
     360        if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) {
     361            $this->flush_number[ $this->blog_prefix ] = $this->get_flush_number( $this->flush_group );
     362        }
     363        return $this->flush_number[ $this->blog_prefix ];
     364    }
     365
    270366    function flush() {
    271367        // Do not use the memcached flush method. It acts on an
     
    273369        // Flush is also unusable in some setups, e.g. twemproxy.
    274370        // Instead, rotate the key prefix for the current site.
    275         // Global keys are rotated when flushing on the main site.
     371        // Global keys are rotated when flushing on any network's
     372        // main site.
    276373        $this->cache = array();
    277374
    278         $this->rotate_site_keys();
     375        $flush_number = $this->new_flush_number();
     376
     377        $this->rotate_site_keys( $flush_number );
    279378
    280379        if ( is_main_site() ) {
    281             $this->rotate_global_keys();
    282         }
    283     }
    284 
    285     function rotate_site_keys() {
    286         $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache' );
    287 
    288         $this->flush_number[ $this->blog_prefix ] = $this->incr( 'flush_number', 1, 'WP_Object_Cache' );
    289     }
    290 
    291     function rotate_global_keys() {
    292         $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache_global' );
    293 
    294         $this->global_flush_number = $this->incr( 'flush_number', 1, 'WP_Object_Cache_global' );
     380            $this->rotate_global_keys( $flush_number );
     381        }
     382    }
     383
     384    function rotate_site_keys( $flush_number = null ) {
     385        if ( is_null( $flush_number ) ) {
     386            $flush_number = $this->new_flush_number();
     387        }
     388
     389        $this->set_flush_number( $flush_number, $this->flush_group );
     390
     391        $this->flush_number[ $this->blog_prefix ] = $flush_number;
     392    }
     393
     394    function rotate_global_keys( $flush_number = null ) {
     395        if ( is_null( $flush_number ) ) {
     396            $flush_number = $this->new_flush_number();
     397        }
     398
     399        $this->set_flush_number( $flush_number, $this->global_flush_group );
     400
     401        $this->global_flush_number = $flush_number;
     402    }
     403
     404    function new_flush_number() {
     405        return intval( microtime( true ) * 1e6 );
    295406    }
    296407
     
    418529
    419530    function flush_prefix( $group ) {
    420         if ( 'WP_Object_Cache' === $group || 'WP_Object_Cache_global' === $group ) {
     531        if ( $group === $this->flush_group || $group === $this->global_flush_group ) {
    421532            // Never flush the flush numbers.
    422533            $number = '_';
    423534        } elseif ( false !== array_search( $group, $this->global_groups ) ) {
    424             if ( ! isset( $this->global_flush_number ) ) {
    425                 $this->global_flush_number = intval( $this->get( 'flush_number', 'WP_Object_Cache_global' ) );
    426             }
    427 
    428             if ( 0 === $this->global_flush_number ) {
    429                 $this->rotate_global_keys();
    430             }
    431 
    432             $number = $this->global_flush_number;
     535            $number = $this->get_global_flush_number();
    433536        } else {
    434             if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) {
    435                 $this->flush_number[ $this->blog_prefix ] = intval( $this->get( 'flush_number', 'WP_Object_Cache' ) );
    436             }
    437 
    438             if ( 0 === $this->flush_number[ $this->blog_prefix ] ) {
    439                 $this->rotate_site_keys();
    440             }
    441 
    442             $number = $this->flush_number[ $this->blog_prefix ];
    443         }
    444 
     537            $number = $this->get_blog_flush_number();
     538        }
    445539        return $number . ':';
    446540    }
     
    616710        }
    617711
    618         echo "<ul class='debug-menu-links'>\n";
     712        echo "<ul class='debug-menu-links' style='clear:left;font-size:14px;'>\n";
    619713        $groups = array_keys( $this->group_ops );
    620714        usort( $groups, 'strnatcasecmp' );
     
    755849            $this->mc[ $bucket ] = new Memcache();
    756850
    757             foreach ( $servers as $server  ) {
     851            foreach ( $servers as $i => $server  ) {
    758852                if ( 'unix://' == substr( $server, 0, 7 ) ) {
    759853                    $node = $server;
     
    775869                $this->mc[ $bucket ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) );
    776870                $this->mc[ $bucket ]->setCompressThreshold( 20000, 0.2 );
     871
     872                // Prepare individual connections to servers in default bucket for flush_number redundancy
     873                if ( 'default' === $bucket ) {
     874                    $this->default_mcs[ $i ] = new Memcache();
     875                    $this->default_mcs[ $i ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) );
     876                }
    777877            }
    778878        }
     
    827927
    828928    /**
    829      * Key format: key_salt:flush_timer:table_prefix:key_name
     929     * Key format: key_salt:flush_number:table_prefix:key_name
    830930     *
    831      * We want to strip the `key_salt:flush_timer` part to not leak the memcached keys.
    832      * If `key_salt` is set we strip `'key_salt:flush_timer`, otherwise just strip the `flush_timer` part.
     931     * We want to strip the `key_salt:flush_number` part to not leak the memcached keys.
     932     * If `key_salt` is set we strip `'key_salt:flush_number`, otherwise just strip the `flush_number` part.
    833933     */
    834934    function strip_memcached_keys( $keys ) {
  • memcached/trunk/readme.txt

    r2317344 r2571100  
    33Tags: cache, memcached
    44Requires at least: 5.3
    5 Tested up to: 5.4.1
    6 Stable tag: 3.2.2
     5Tested up to: 5.8
     6Stable tag: 4.0.0
    77Requires PHP: 5.6.20
    88
     
    8484== Changelog ==
    8585
     86= 4.0.0 =
     87* Add preemptive filter pre_wp_cache_get
     88* Add flush_number replication to prevent accidental flush due to flush_number eviction, server rotation, etc.
     89
    8690= 3.2.2 =
    8791* Remove filter, and base key stripping on presence of `key_salt`
Note: See TracChangeset for help on using the changeset viewer.