WordPress.org

Make WordPress Core

Changeset 6539


Ignore:
Timestamp:
01/02/08 22:13:16 (8 years ago)
Author:
ryan
Message:

Remove persistent object cache. fixes #5570

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/cache.php

    r6247 r6539  
    22function wp_cache_add($key, $data, $flag = '', $expire = 0) { 
    33    global $wp_object_cache; 
    4     $data = unserialize(serialize($data)); 
    54 
    65    return $wp_object_cache->add($key, $data, $flag, $expire); 
     
    3938function wp_cache_replace($key, $data, $flag = '', $expire = 0) { 
    4039    global $wp_object_cache; 
    41     $data = unserialize(serialize($data)); 
    4240 
    4341    return $wp_object_cache->replace($key, $data, $flag, $expire); 
     
    4644function wp_cache_set($key, $data, $flag = '', $expire = 0) { 
    4745    global $wp_object_cache; 
    48     $data = unserialize(serialize($data)); 
    4946 
    5047    return $wp_object_cache->set($key, $data, $flag, $expire); 
    5148} 
    5249 
    53 define('CACHE_SERIAL_HEADER', "<?php\n/*"); 
    54 define('CACHE_SERIAL_FOOTER', "*/\n?".">"); 
    55  
    5650class WP_Object_Cache { 
    57     var $cache_dir; 
    58     var $cache_enabled = false; 
    59     var $expiration_time = 900; 
    60     var $flock_filename = 'wp_object_cache.lock'; 
    61     var $mutex; 
    6251    var $cache = array (); 
    63     var $dirty_objects = array (); 
    6452    var $non_existant_objects = array (); 
    6553    var $global_groups = array ('users', 'userlogins', 'usermeta'); 
    66     var $non_persistent_groups = array('comment'); 
    67     var $blog_id; 
    68     var $cold_cache_hits = 0; 
    69     var $warm_cache_hits = 0; 
     54    var $cache_hits = 0; 
    7055    var $cache_misses = 0; 
    71     var $secret = ''; 
    72  
    73     function acquire_lock() { 
    74         // Acquire a write lock. 
    75         $this->mutex = @fopen($this->cache_dir.$this->flock_filename, 'w'); 
    76         if ( false == $this->mutex) 
    77             return false; 
    78         flock($this->mutex, LOCK_EX); 
    79         return true; 
    80     } 
    8156 
    8257    function add($id, $data, $group = 'default', $expire = '') { 
     
    9974        unset ($this->cache[$group][$id]); 
    10075        $this->non_existant_objects[$group][$id] = true; 
    101         $this->dirty_objects[$group][] = $id; 
    10276        return true; 
    10377    } 
    10478 
    10579    function flush() { 
    106         if ( !$this->cache_enabled ) 
    107             return true; 
    108  
    109         if ( ! $this->acquire_lock() ) 
    110             return false; 
    111  
    112         $this->rm_cache_dir(); 
    11380        $this->cache = array (); 
    114         $this->dirty_objects = array (); 
    115         $this->non_existant_objects = array (); 
    116  
    117         $this->release_lock(); 
    11881 
    11982        return true; 
    12083    } 
    12184 
    122     function get($id, $group = 'default', $count_hits = true) { 
     85    function get($id, $group = 'default') { 
    12386        if (empty ($group)) 
    12487            $group = 'default'; 
    12588 
    12689        if (isset ($this->cache[$group][$id])) { 
    127             if ($count_hits) 
    128                 $this->warm_cache_hits += 1; 
     90            $this->cache_hits += 1; 
    12991            return $this->cache[$group][$id]; 
    13092        } 
    13193 
    132         if (isset ($this->non_existant_objects[$group][$id])) 
     94        if ( isset ($this->non_existant_objects[$group][$id]) ) 
    13395            return false; 
    13496 
    135         //  If caching is not enabled, we have to fall back to pulling from the DB. 
    136         if (!$this->cache_enabled) { 
    137             if (!isset ($this->cache[$group])) 
    138                 $this->load_group_from_db($group); 
    139  
    140             if (isset ($this->cache[$group][$id])) { 
    141                 $this->cold_cache_hits += 1; 
    142                 return $this->cache[$group][$id]; 
    143             } 
    144  
    145             $this->non_existant_objects[$group][$id] = true; 
    146             $this->cache_misses += 1; 
    147             return false; 
    148         } 
    149  
    150         $cache_file = $this->cache_dir.$this->get_group_dir($group)."/".$this->hash($id).'.php'; 
    151         if (!file_exists($cache_file)) { 
    152             $this->non_existant_objects[$group][$id] = true; 
    153             $this->cache_misses += 1; 
    154             return false; 
    155         } 
    156  
    157         // If the object has expired, remove it from the cache and return false to force 
    158         // a refresh. 
    159         $now = time(); 
    160         if ((filemtime($cache_file) + $this->expiration_time) <= $now) { 
    161             $this->cache_misses += 1; 
    162             $this->delete($id, $group, true); 
    163             return false; 
    164         } 
    165  
    166         $this->cache[$group][$id] = unserialize(base64_decode(substr(@ file_get_contents($cache_file), strlen(CACHE_SERIAL_HEADER), -strlen(CACHE_SERIAL_FOOTER)))); 
    167         if (false === $this->cache[$group][$id]) 
    168             $this->cache[$group][$id] = ''; 
    169  
    170         $this->cold_cache_hits += 1; 
    171         return $this->cache[$group][$id]; 
    172     } 
    173  
    174     function get_group_dir($group) { 
    175         if (false !== array_search($group, $this->global_groups)) 
    176             return $group; 
    177  
    178         return "{$this->blog_id}/$group"; 
    179     } 
    180  
    181     function hash($data) { 
    182         if ( function_exists('hash_hmac') ) { 
    183             return hash_hmac('md5', $data, $this->secret); 
    184         } else { 
    185             return md5($data . $this->secret); 
    186         } 
    187     } 
    188  
    189     function load_group_from_db($group) { 
    190         return; 
    191     } 
    192  
    193     function make_group_dir($group, $perms) { 
    194         $group_dir = $this->get_group_dir($group); 
    195         $make_dir = ''; 
    196         foreach (split('/', $group_dir) as $subdir) { 
    197             $make_dir .= "$subdir/"; 
    198             if (!file_exists($this->cache_dir.$make_dir)) { 
    199                 if (! @ mkdir($this->cache_dir.$make_dir)) 
    200                     break; 
    201                 @ chmod($this->cache_dir.$make_dir, $perms); 
    202             } 
    203  
    204             if (!file_exists($this->cache_dir.$make_dir."index.php")) { 
    205                 $file_perms = $perms & 0000666; 
    206                 @ touch($this->cache_dir.$make_dir."index.php"); 
    207                 @ chmod($this->cache_dir.$make_dir."index.php", $file_perms); 
    208             } 
    209         } 
    210  
    211         return $this->cache_dir."$group_dir/"; 
    212     } 
    213  
    214     function rm_cache_dir() { 
    215         $dir = $this->cache_dir; 
    216         $dir = rtrim($dir, DIRECTORY_SEPARATOR); 
    217         $top_dir = $dir; 
    218         $stack = array($dir); 
    219         $index = 0; 
    220  
    221         while ($index < count($stack)) { 
    222             # Get indexed directory from stack 
    223             $dir = $stack[$index]; 
    224  
    225             $dh = @ opendir($dir); 
    226             if (!$dh) 
    227                 return false; 
    228  
    229             while (($file = @ readdir($dh)) !== false) { 
    230                 if ($file == '.' or $file == '..') 
    231                     continue; 
    232  
    233                 if (@ is_dir($dir . DIRECTORY_SEPARATOR . $file)) 
    234                     $stack[] = $dir . DIRECTORY_SEPARATOR . $file; 
    235                 else if (@ is_file($dir . DIRECTORY_SEPARATOR . $file)) 
    236                     @ unlink($dir . DIRECTORY_SEPARATOR . $file); 
    237             } 
    238  
    239             $index++; 
    240         } 
    241  
    242         $stack = array_reverse($stack);  // Last added dirs are deepest 
    243         foreach($stack as $dir) { 
    244             if ( $dir != $top_dir) 
    245                 @ rmdir($dir); 
    246         } 
    247  
    248     } 
    249  
    250     function release_lock() { 
    251         // Release write lock. 
    252         flock($this->mutex, LOCK_UN); 
    253         fclose($this->mutex); 
     97        $this->non_existant_objects[$group][$id] = true; 
     98        $this->cache_misses += 1; 
     99        return false; 
    254100    } 
    255101 
     
    273119        $this->cache[$group][$id] = $data; 
    274120        unset ($this->non_existant_objects[$group][$id]); 
    275         $this->dirty_objects[$group][] = $id; 
    276  
    277         return true; 
    278     } 
    279  
    280     function save() { 
    281         //$this->stats(); 
    282  
    283         if (!$this->cache_enabled) 
    284             return true; 
    285  
    286         if (empty ($this->dirty_objects)) 
    287             return true; 
    288  
    289         // Give the new dirs the same perms as wp-content. 
    290         $stat = stat(ABSPATH.'wp-content'); 
    291         $dir_perms = $stat['mode'] & 0007777; // Get the permission bits. 
    292         $file_perms = $dir_perms & 0000666; // Remove execute bits for files. 
    293  
    294         // Make the base cache dir. 
    295         if (!file_exists($this->cache_dir)) { 
    296             if (! @ mkdir($this->cache_dir)) 
    297                 return false; 
    298             @ chmod($this->cache_dir, $dir_perms); 
    299         } 
    300  
    301         if (!file_exists($this->cache_dir."index.php")) { 
    302             @ touch($this->cache_dir."index.php"); 
    303             @ chmod($this->cache_dir."index.php", $file_perms); 
    304         } 
    305  
    306         if ( ! $this->acquire_lock() ) 
    307             return false; 
    308  
    309         // Loop over dirty objects and save them. 
    310         $errors = 0; 
    311         foreach ($this->dirty_objects as $group => $ids) { 
    312             if ( in_array($group, $this->non_persistent_groups) ) 
    313                 continue; 
    314  
    315             $group_dir = $this->make_group_dir($group, $dir_perms); 
    316  
    317             $ids = array_unique($ids); 
    318             foreach ($ids as $id) { 
    319                 $cache_file = $group_dir.$this->hash($id).'.php'; 
    320  
    321                 // Remove the cache file if the key is not set. 
    322                 if (!isset ($this->cache[$group][$id])) { 
    323                     if (file_exists($cache_file)) 
    324                         @ unlink($cache_file); 
    325                     continue; 
    326                 } 
    327  
    328                 $temp_file = tempnam($group_dir, 'tmp'); 
    329                 $serial = CACHE_SERIAL_HEADER.base64_encode(serialize($this->cache[$group][$id])).CACHE_SERIAL_FOOTER; 
    330                 $fd = @fopen($temp_file, 'w'); 
    331                 if ( false === $fd ) { 
    332                     $errors++; 
    333                     continue; 
    334                 } 
    335                 fputs($fd, $serial); 
    336                 fclose($fd); 
    337                 if (!@ rename($temp_file, $cache_file)) { 
    338                     if (!@ copy($temp_file, $cache_file)) 
    339                         $errors++; 
    340                     @ unlink($temp_file); 
    341                 } 
    342                 @ chmod($cache_file, $file_perms); 
    343             } 
    344         } 
    345  
    346         $this->dirty_objects = array(); 
    347  
    348         $this->release_lock(); 
    349  
    350         if ( $errors ) 
    351             return false; 
    352121 
    353122        return true; 
     
    356125    function stats() { 
    357126        echo "<p>"; 
    358         echo "<strong>Cold Cache Hits:</strong> {$this->cold_cache_hits}<br />"; 
    359         echo "<strong>Warm Cache Hits:</strong> {$this->warm_cache_hits}<br />"; 
     127        echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />"; 
    360128        echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />"; 
    361129        echo "</p>"; 
     
    368136            print_r($cache); 
    369137            echo "</pre>"; 
    370             if (isset ($this->dirty_objects[$group])) { 
    371                 echo "<strong>Dirty Objects:</strong>"; 
    372                 echo "<pre>"; 
    373                 print_r(array_unique($this->dirty_objects[$group])); 
    374                 echo "</pre>"; 
    375                 echo "</p>"; 
    376             } 
    377138        } 
    378139    } 
     
    383144 
    384145    function __construct() { 
    385         global $blog_id; 
    386  
    387146        register_shutdown_function(array(&$this, "__destruct")); 
    388  
    389         if (defined('DISABLE_CACHE')) 
    390             return; 
    391  
    392         if ( ! defined('ENABLE_CACHE') ) 
    393             return; 
    394  
    395         // Disable the persistent cache if safe_mode is on. 
    396         if ( ini_get('safe_mode') && ! defined('ENABLE_CACHE') ) 
    397             return; 
    398  
    399         if (defined('CACHE_PATH')) 
    400             $this->cache_dir = CACHE_PATH; 
    401         else 
    402             // Using the correct separator eliminates some cache flush errors on Windows 
    403             $this->cache_dir = ABSPATH.'wp-content'.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR; 
    404  
    405         if (is_writable($this->cache_dir) && is_dir($this->cache_dir)) { 
    406                 $this->cache_enabled = true; 
    407         } else { 
    408             if (is_writable(ABSPATH.'wp-content')) { 
    409                 $this->cache_enabled = true; 
    410             } 
    411         } 
    412  
    413         if (defined('CACHE_EXPIRATION_TIME')) 
    414             $this->expiration_time = CACHE_EXPIRATION_TIME; 
    415  
    416         if ( defined('WP_SECRET') ) 
    417             $this->secret = WP_SECRET; 
    418         else 
    419             $this->secret = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH; 
    420  
    421         $this->blog_id = $this->hash($blog_id); 
    422147    } 
    423148 
    424149    function __destruct() { 
    425         $this->save(); 
    426150        return true; 
    427151    } 
Note: See TracChangeset for help on using the changeset viewer.