diff --git a/dmemcache.inc b/dmemcache.inc index 63af64d6a04dc2cd7073f92a5a5feb30f686218f..1b73c2fb4ac6e5d1cf125a0b39e2030357129be4 100644 --- a/dmemcache.inc +++ b/dmemcache.inc @@ -1,36 +1,41 @@ array(), 'ops' => array()); -/* - * A memcache API for Drupal. - */ - /** - * Place an item into memcache + * Place an item into memcache. * - * @param $key The string with which you will retrieve this item later. - * @param $value The item to be stored. - * @param $exp Parameter expire is expiration time in seconds. If it's 0, the - * item never expires (but memcached server doesn't guarantee this item to be - * stored all the time, it could be deleted from the cache to make place for - * other items). - * @param $bin The name of the Drupal subsystem that is making this call. - * Examples could be 'cache', 'alias', 'taxonomy term' etc. It is possible to - * map different $bin values to different memcache servers. - * @param $mc Optionally pass in the memcache object. Normally this value is - * determined automatically based on the bin the object is being stored to. + * @param string $key + * The string with which you will retrieve this item later. + * @param mixed $value + * The item to be stored. + * @param int $exp + * Parameter expire is expiration time in seconds. If it's 0, the item never + * expires (but memcached server doesn't guarantee this item to be stored all + * the time, it could be deleted from the cache to make place for other + * items). + * @param string $bin + * The name of the Drupal subsystem that is making this call. Examples could + * be 'cache', 'alias', 'taxonomy term' etc. It is possible to map different + * $bin values to different memcache servers. + * @param object $mc + * Optionally pass in the memcache object. Normally this value is determined + * automatically based on the bin the object is being stored to. * * @return bool + * TRUE on succes, FALSE otherwise. */ function dmemcache_set($key, $value, $exp = 0, $bin = 'cache', $mc = NULL) { $collect_stats = dmemcache_stats_init(); @@ -55,25 +60,32 @@ function dmemcache_set($key, $value, $exp = 0, $bin = 'cache', $mc = NULL) { } /** - * Add an item into memcache + * Add an item into memcache. * - * @param $key The string with which you will retrieve this item later. - * @param $value The item to be stored. - * @param $exp Parameter expire is expiration time in seconds. If it's 0, the + * @param string $key + * The string with which you will retrieve this item later. + * @param mixed $value + * The item to be stored. + * @param int $exp + * Parameter expire is expiration time in seconds. If it's 0, the * item never expires (but memcached server doesn't guarantee this item to be * stored all the time, it could be deleted from the cache to make place for * other items). - * @param $bin The name of the Drupal subsystem that is making this call. + * @param string $bin + * The name of the Drupal subsystem that is making this call. * Examples could be 'cache', 'alias', 'taxonomy term' etc. It is possible * to map different $bin values to different memcache servers. - * @param $mc Optionally pass in the memcache object. Normally this value is + * @param object $mc + * Optionally pass in the memcache object. Normally this value is * determined automatically based on the bin the object is being stored to. - * @param $flag If using the older memcache PECL extension as opposed to the + * @param int $flag + * If using the older memcache PECL extension as opposed to the * newer memcached PECL extension, the MEMCACHE_COMPRESSED flag can be set * to use zlib to store a compressed copy of the item. This flag option is * completely ignored when using the newer memcached PECL extension. * * @return bool + * FALSE if placing the item into memcache failed. */ function dmemcache_add($key, $value, $exp = 0, $bin = 'cache', $mc = NULL, $flag = FALSE) { $collect_stats = dmemcache_stats_init(); @@ -100,10 +112,13 @@ function dmemcache_add($key, $value, $exp = 0, $bin = 'cache', $mc = NULL, $flag /** * Retrieve a value from the cache. * - * @param $key The key with which the item was stored. - * @param $bin The bin in which the item was stored. + * @param string $key + * The key with which the item was stored. + * @param string $bin + * The bin in which the item was stored. * - * @return The item which was originally saved or FALSE + * @return mixed + * The item which was originally saved or FALSE */ function dmemcache_get($key, $bin = 'cache', $mc = NULL) { $collect_stats = dmemcache_stats_init(); @@ -135,10 +150,13 @@ function dmemcache_get($key, $bin = 'cache', $mc = NULL) { /** * Retrieve multiple values from the cache. * - * @param $keys The keys with which the items were stored. - * @param $bin The bin in which the item was stored. + * @param array $keys + * The keys with which the items were stored. + * @param string $bin + * The bin in which the item was stored. * - * @return The item which was originally saved or FALSE + * @return mixed + * The item which was originally saved or FALSE */ function dmemcache_get_multi($keys, $bin = 'cache', $mc = NULL) { $collect_stats = dmemcache_stats_init(); @@ -201,10 +219,13 @@ function dmemcache_get_multi($keys, $bin = 'cache', $mc = NULL) { /** * Deletes an item from the cache. * - * @param $key The key with which the item was stored. - * @param $bin The bin in which the item was stored. + * @param string $key + * The key with which the item was stored. + * @param string $bin + * The bin in which the item was stored. * - * @return Returns TRUE on success or FALSE on failure. + * @return bool + * Returns TRUE on success or FALSE on failure. */ function dmemcache_delete($key, $bin = 'cache', $mc = NULL) { $collect_stats = dmemcache_stats_init(); @@ -224,14 +245,18 @@ function dmemcache_delete($key, $bin = 'cache', $mc = NULL) { } /** - * Immediately invalidates all existing items. dmemcache_flush doesn't actually free any - * resources, it only marks all the items as expired, so occupied memory will be overwritten by - * new items. + * Flush all stored items. + * + * Immediately invalidates all existing items. dmemcache_flush doesn't actually + * free any resources, it only marks all the items as expired, so occupied + * memory will be overwritten by new items. * - * @param $bin The bin to flush. Note that this will flush all bins mapped to the same server - * as $bin. There is no way at this time to empty just one bin. + * @param string $bin + * The bin to flush. Note that this will flush all bins mapped to the same + * server as $bin. There is no way at this time to empty just one bin. * - * @return Returns TRUE on success or FALSE on failure. + * @return bool + * Returns TRUE on success or FALSE on failure. */ function dmemcache_flush($bin = 'cache', $mc = NULL) { $collect_stats = dmemcache_stats_init(); @@ -251,11 +276,21 @@ function dmemcache_flush($bin = 'cache', $mc = NULL) { return $rc; } +/** + * Retrieves statistics recorded during memcache operations. + * + * @param string $stats_bin + * The bin to retrieve statistics for. + * @param string $stats_type + * The type of statistics to retrieve when using the Memcache extension. + * @param bool $aggregate + * Whether to aggregate statistics. + */ function dmemcache_stats($stats_bin = 'cache', $stats_type = 'default', $aggregate = FALSE) { $memcache_bins = variable_get('memcache_bins', array('cache' => 'default')); // The stats_type can be over-loaded with an integer slab id, if doing a // cachedump. We know we're doing a cachedump if $slab is non-zero. - $slab = (int)$stats_type; + $slab = (int) $stats_type; foreach ($memcache_bins as $bin => $target) { if ($stats_bin == $bin) { @@ -267,13 +302,13 @@ function dmemcache_stats($stats_bin = 'cache', $stats_type = 'default', $aggrega // type is NULL or not in {reset, malloc, slabs, cachedump, items, // sizes}. If $stats_type is 'default', then no parameter should be // passed to the Memcache memcache_get_extended_stats() function. - else if ($mc instanceof Memcache) { + elseif ($mc instanceof Memcache) { if ($stats_type == 'default' || $stats_type == '') { $stats[$bin] = $mc->getExtendedStats(); } // If $slab isn't zero, then we are dumping the contents of a // specific cache slab. - else if (!empty($slab)) { + elseif (!empty($slab)) { $stats[$bin] = $mc->getStats('cachedump', $slab); } else { @@ -286,8 +321,15 @@ function dmemcache_stats($stats_bin = 'cache', $stats_type = 'default', $aggrega // Optionally calculate a sum-total for all servers in the current bin. if ($aggregate) { // Some variables don't logically aggregate. - $no_aggregate = array('pid', 'time', 'version', 'pointer_size', 'accepting_conns', 'listen_disabled_num'); - foreach($stats as $bin => $servers) { + $no_aggregate = array( + 'pid', + 'time', + 'version', + 'pointer_size', + 'accepting_conns', + 'listen_disabled_num', + ); + foreach ($stats as $bin => $servers) { if (is_array($servers)) { foreach ($servers as $server) { if (is_array($server)) { @@ -344,10 +386,10 @@ function dmemcache_instance() { static $error = FALSE; $extension = dmemcache_extension(); if ($extension == 'Memcache') { - return new Memcache; + return new Memcache(); } elseif ($extension == 'Memcached') { - $memcache = new Memcached; + $memcache = new Memcached(); $default_opts = array( Memcached::OPT_COMPRESSION => FALSE, Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT, @@ -375,15 +417,17 @@ function dmemcache_instance() { /** * Initiate a connection to memcache. * - * @param $memcache A memcache instance obtained through dmemcache_instance. - * - * @param $server A server string of the format "localhost:11211" or + * @param object $memcache + * A memcache instance obtained through dmemcache_instance. + * @param string $server + * A server string of the format "localhost:11211" or * "unix:///path/to/socket". + * @param bool $connection + * TRUE or FALSE, whether the $memcache instance already has at least one + * open connection. * - * @connection TRUE or FALSE, whether the $memcache instance already has at - * least one open connection. - * - * @return TRUE or FALSE if connection was successful. + * @return bool + * TRUE or FALSE if connection was successful. */ function dmemcache_connect($memcache, $server, $connection) { static $memcache_persistent = NULL; @@ -432,7 +476,7 @@ function dmemcache_connect($memcache, $server, $connection) { $rc = $memcache->addServer($host, $port, $memcache_persistent); } } - else if ($extension == 'Memcached') { + elseif ($extension == 'Memcached') { // Support unix sockets of the format 'unix:///path/to/socket'. if ($host == 'unix') { // Strip 'unix://' as expected by Memcached extension. @@ -455,7 +499,7 @@ function dmemcache_close($memcache) { if ($extension == 'Memcache' && $memcache instanceof Memcache) { $rc = @$memcache->close; } - else if ($extension == 'Memcached' && $memcache instanceof Memcached) { + elseif ($extension == 'Memcached' && $memcache instanceof Memcached) { $rc = @$memcache->quit; } else { @@ -472,28 +516,30 @@ function dmemcache_close($memcache) { * provided by this API or if you need to use legacy code. Otherwise, use the * dmemcache (get, set, delete, flush) API functions provided here. * - * @param $bin The bin which is to be used. - * - * @param $flush Rebuild the bin/server/cache mapping. + * @param string $bin + * The bin which is to be used. + * @param bool $flush + * Defaults to FALSE. Rebuild the bin/server/cache mapping. * - * @return a Memcache object or FALSE. + * @return mixed + * A Memcache object, or FALSE on failure. */ function dmemcache_object($bin = NULL, $flush = FALSE) { - static $memcacheCache = array(); + static $memcache_cache = array(); static $memcache_servers = array(); static $memcache_bins = array(); static $failed_connections = array(); if ($flush) { - foreach ($memcacheCache as $cluster) { + foreach ($memcache_cache as $cluster) { memcache_close($cluster); } - $memcacheCache = array(); + $memcache_cache = array(); } $extension = dmemcache_extension(); - if (empty($memcacheCache) || empty($memcacheCache[$bin])) { + if (empty($memcache_cache) || empty($memcache_cache[$bin])) { if (empty($memcache_servers)) { // Load the variables from settings.php if set. $memcache_servers = variable_get('memcache_servers', array('127.0.0.1:11211' => 'default')); @@ -505,8 +551,8 @@ function dmemcache_object($bin = NULL, $flush = FALSE) { // If not manually set, map this bin to 'cache' which maps to the 'default' // cluster. - if (empty($memcache_bins[$bin]) && !empty($memcacheCache['cache'])) { - $memcacheCache[$bin] = &$memcacheCache['cache']; + if (empty($memcache_bins[$bin]) && !empty($memcache_cache['cache'])) { + $memcache_cache[$bin] = &$memcache_cache['cache']; } else { // Create a new memcache object for each cluster. @@ -535,23 +581,34 @@ function dmemcache_object($bin = NULL, $flush = FALSE) { } if ($connection) { // Map the current bin with the new Memcache object. - $memcacheCache[$bin] = $memcache; + $memcache_cache[$bin] = $memcache; // Now that all the servers have been mapped to this cluster, look for // other bins that belong to the cluster and map them too. foreach ($memcache_bins as $b => $c) { if ($c == $cluster && $b != $bin) { // Map this bin and cluster by reference. - $memcacheCache[$b] = &$memcacheCache[$bin]; + $memcache_cache[$b] = &$memcache_cache[$bin]; } } } } } - return empty($memcacheCache[$bin]) ? FALSE : $memcacheCache[$bin]; + return empty($memcache_cache[$bin]) ? FALSE : $memcache_cache[$bin]; } +/** + * Prefixes a key and ensures it is url safe. + * + * @param string $key + * The key to prefix and encode. + * @param string $bin + * The cache bin which the key applies to. + * + * @return string + * The prefixed and encoded key. + */ function dmemcache_key($key, $bin = 'cache') { $prefix = ''; if ($prefix = variable_get('memcache_key_prefix', '')) { @@ -578,10 +635,12 @@ function dmemcache_key($key, $bin = 'cache') { /** * Collect statistics if enabled. * - * Optimized function to determine whether or not we should be collecting statistics. Also starts a - * timer to track how long individual memcache operations take. + * Optimized function to determine whether or not we should be collecting + * statistics. Also starts a timer to track how long individual memcache + * operations take. * - * @return TRUE or FALSE if statistics should be collected. + * @return bool + * TRUE or FALSE if statistics should be collected. */ function dmemcache_stats_init() { static $drupal_static_fast; @@ -593,9 +652,9 @@ function dmemcache_stats_init() { $user_access_checked = &$drupal_static_fast['user_access_checked']; // Confirm DRUPAL_BOOTSTRAP_VARIABLES has been reached. We don't use - // drupal_get_bootstrap_phase() as it's buggy. We can use variable_get() here because - // _drupal_bootstrap_variables() includes module.inc immediately after it calls - // variable_initialize(). + // drupal_get_bootstrap_phase() as it's buggy. We can use variable_get() here + // because _drupal_bootstrap_variables() includes module.inc immediately + // after it calls variable_initialize(). if (!isset($variable_checked) && function_exists('module_list')) { $variable_checked = variable_get('show_memcache_statistics', FALSE); } @@ -618,9 +677,13 @@ function dmemcache_stats_init() { /** * Save memcache statistics to be displayed at end of page generation. * - * @param $action The action being performed (get, set, etc...). - * @param $bin The memcache bin the action is being performed in. - * @param $keys The key the action is being performed on, and whether or not it was a success. + * @param string $action + * The action being performed (get, set, etc...). + * @param string $bin + * The memcache bin the action is being performed in. + * @param array $keys + * Keyed array in the form (string)$cid => (bool)$success. The keys the + * action is being performed on, and whether or not it was a success. */ function dmemcache_stats_write($action, $bin, $keys) { global $_dmemcache_stats, $timers; @@ -628,12 +691,23 @@ function dmemcache_stats_write($action, $bin, $keys) { $time = timer_read('dmemcache'); // Build the 'all' and 'ops' arrays displayed by memcache_admin.module. foreach ($keys as $key => $success) { - $_dmemcache_stats['all'][] = array(number_format($time, 2), $action, $bin, $key, $success ? 'hit' : 'miss'); + $_dmemcache_stats['all'][] = array( + number_format($time, 2), + $action, + $bin, + $key, + $success ? 'hit' : 'miss', + ); if (!isset($_dmemcache_stats['ops'][$action])) { $_dmemcache_stats['ops'][$action] = array($action, 0, 0, 0); } $_dmemcache_stats['ops'][$action][1] += $time; - $success ? $_dmemcache_stats['ops'][$action][2]++ : $_dmemcache_stats['ops'][$action][3]++; + if ($success) { + $_dmemcache_stats['ops'][$action][2]++; + } + else { + $_dmemcache_stats['ops'][$action][3]++; + } } // Reset the dmemcache timer for timing the next memcache operation. unset($timers['dmemcache']); diff --git a/memcache-lock-code.inc b/memcache-lock-code.inc index 15e32831c2b4ca398d59a82756e84383fbfa2116..fbf459e0e01ab9272af5b23162d78e31c50f2f2f 100644 --- a/memcache-lock-code.inc +++ b/memcache-lock-code.inc @@ -21,11 +21,12 @@ function lock_initialize() { /** * Acquire (or renew) a lock, but do not block if it fails. * - * @param $name + * @param string $name * The name of the lock. - * @param $timeout + * @param int $timeout * A number of seconds (int) before the lock expires (minimum of 1). - * @return + * + * @return bool * TRUE if the lock was acquired, FALSE if it failed. */ function lock_acquire($name, $timeout = 30) { @@ -56,9 +57,10 @@ function lock_acquire($name, $timeout = 30) { * * If an existing lock has expired, it is removed. * - * @param $name + * @param string $name * The name of the lock. - * @return + * + * @return bool * TRUE if there is no lock or it was removed, FALSE otherwise. */ function lock_may_be_available($name) { @@ -74,23 +76,26 @@ function lock_may_be_available($name) { * that are acquired very frequently, since the lock is likely to be acquired * again by a different request while waiting. * - * @param $name + * @param string $name * The name of the lock. - * @param $delay + * @param int $delay * The maximum number of seconds to wait, as an integer. - * @return + * + * @return bool * TRUE if the lock holds, FALSE if it is available. */ function lock_wait($name, $delay = 30) { - // Pause the process for short periods between calling - // lock_may_be_available(). This prevents hitting the database with constant - // database queries while waiting, which could lead to performance issues. - // However, if the wait period is too long, there is the potential for a - // large number of processes to be blocked waiting for a lock, especially - // if the item being rebuilt is commonly requested. To address both of these - // concerns, begin waiting for 25ms, then add 25ms to the wait period each - // time until it reaches 500ms. After this point polling will continue every - // 500ms until $delay is reached. + /* + * Pause the process for short periods between calling + * lock_may_be_available(). This prevents hitting the database with constant + * database queries while waiting, which could lead to performance issues. + * However, if the wait period is too long, there is the potential for a + * large number of processes to be blocked waiting for a lock, especially + * if the item being rebuilt is commonly requested. To address both of these + * concerns, begin waiting for 25ms, then add 25ms to the wait period each + * time until it reaches 500ms. After this point polling will continue every + * 500ms until $delay is reached. + */ // $delay is passed in seconds, but we will be using usleep(), which takes // microseconds as a parameter. Multiply it by 1 million so that all @@ -122,7 +127,7 @@ function lock_wait($name, $delay = 30) { * * This will release the named lock if it is still held by the current request. * - * @param $name + * @param string $name * The name of the lock. */ function lock_release($name) { diff --git a/memcache-lock.inc b/memcache-lock.inc index bc0f936843c995c4e971b3c21ec1d05757c7c31a..ef176dfe240a2d773aff86dc9d56cae9e7a54713 100644 --- a/memcache-lock.inc +++ b/memcache-lock.inc @@ -15,4 +15,4 @@ $lock_file = dirname(__FILE__) . '/memcache-lock-code.inc'; if (!dmemcache_object('semaphore')) { $lock_file = DRUPAL_ROOT . '/includes/lock.inc'; } -require_once $lock_file; \ No newline at end of file +require_once $lock_file; diff --git a/memcache.inc b/memcache.inc index 41b6bf4bdd7b39abe98a982cc1d5ec40bb232827..e0600d7473d764cb50bb154733fb57bfd242af40 100644 --- a/memcache.inc +++ b/memcache.inc @@ -1,18 +1,31 @@ memcache = dmemcache_object($bin); $this->bin = $bin; @@ -40,12 +53,18 @@ class MemCacheDrupal implements DrupalCacheInterface { $this->reloadVariables(); } - function get($cid) { + /** + * Implements DrupalCacheInterface::get(). + */ + public function get($cid) { $cache = dmemcache_get($cid, $this->bin, $this->memcache); return $this->valid($cid, $cache) ? $cache : FALSE; } - function getMultiple(&$cids) { + /** + * Implements DrupalCacheInterface::getMultiple(). + */ + public function getMultiple(&$cids) { $results = dmemcache_get_multi($cids, $this->bin, $this->memcache); foreach ($results as $cid => $result) { if (!$this->valid($cid, $result)) { @@ -59,15 +78,26 @@ class MemCacheDrupal implements DrupalCacheInterface { return $results; } + /** + * Checks if a retrieved cache item is valid. + * + * @param string $cid + * The cache id of the item + * @param mixed $cache + * The cache item. + * + * @return bool + * Whether the item is valid. + */ protected function valid($cid, $cache) { if ($cache) { $cache_tables = isset($_SESSION['cache_flush']) ? $_SESSION['cache_flush'] : NULL; // Items that have expired are invalid. if (isset($cache->expire) && $cache->expire !== CACHE_PERMANENT && $cache->expire <= $_SERVER['REQUEST_TIME']) { - // If the memcache_stampede_protection variable is set, allow one process - // to rebuild the cache entry while serving expired content to the - // rest. Note that core happily returns expired cache items as valid and - // relies on cron to expire them, but this is mostly reliant on its + // If the memcache_stampede_protection variable is set, allow one + // process to rebuild the cache entry while serving expired content to + // the rest. Note that core happily returns expired cache items as valid + // and relies on cron to expire them, but this is mostly reliant on its // use of CACHE_TEMPORARY which does not map well to memcache. // @see http://drupal.org/node/534092 if (variable_get('memcache_stampede_protection', FALSE)) { @@ -105,7 +135,7 @@ class MemCacheDrupal implements DrupalCacheInterface { } // Finally, check for wildcard clears against this cid. else { - if (!$this->wildcard_valid($cid, $cache)) { + if (!$this->wildcardValid($cid, $cache)) { $cache = FALSE; } } @@ -127,9 +157,9 @@ class MemCacheDrupal implements DrupalCacheInterface { static $lock_count = 0; $lock_count++; if ($lock_count <= variable_get('memcache_stampede_wait_limit', 3)) { - // The memcache_stampede_semaphore variable was used in previous releases - // of memcache, but the max_wait variable was not, so by default divide - // the semaphore value by 3 (5 seconds). + // The memcache_stampede_semaphore variable was used in previous + // releases of memcache, but the max_wait variable was not, so by + // default divide the semaphore value by 3 (5 seconds). lock_wait("memcache_$cid:$this->bin", variable_get('memcache_stampede_wait_time', 5)); $cache = $this->get($cid); } @@ -139,16 +169,19 @@ class MemCacheDrupal implements DrupalCacheInterface { return (bool) $cache; } - function set($cid, $data, $expire = CACHE_PERMANENT) { + /** + * Implements DrupalCacheInterface::set(). + */ + public function set($cid, $data, $expire = CACHE_PERMANENT) { $created = time(); // Create new cache object. - $cache = new stdClass; + $cache = new stdClass(); $cache->cid = $cid; $cache->data = is_object($data) ? clone $data : $data; $cache->created = $created; // Record the previous number of wildcard flushes affecting our cid. - $cache->flushes = $this->wildcard_flushes($cid); + $cache->flushes = $this->wildcardFlushes($cid); if ($expire == CACHE_TEMPORARY) { // Convert CACHE_TEMPORARY (-1) into something that will live in memcache // until the next flush. @@ -157,7 +190,7 @@ class MemCacheDrupal implements DrupalCacheInterface { $cache->temporary = TRUE; } // Expire time is in seconds if less than 30 days, otherwise is a timestamp. - else if ($expire != CACHE_PERMANENT && $expire < 2592000) { + elseif ($expire != CACHE_PERMANENT && $expire < 2592000) { // Expire is expressed in seconds, convert to the proper future timestamp // as expected in dmemcache_get(). $cache->expire = REQUEST_TIME + $expire; @@ -189,7 +222,10 @@ class MemCacheDrupal implements DrupalCacheInterface { } } - function clear($cid = NULL, $wildcard = FALSE) { + /** + * Implements DrupalCacheInterface::clear(). + */ + public function clear($cid = NULL, $wildcard = FALSE) { if ($this->memcache === FALSE) { // No memcache connection. return; @@ -248,9 +284,9 @@ class MemCacheDrupal implements DrupalCacheInterface { if ($this->cache_lifetime) { // We store the time in the current user's session which is saved into - // the sessions table by sess_write(). We then simulate that the cache - // was flushed for this user by not returning cached data to this user - // that was cached before the timestamp. + // the sessions table by sess_write(). We then simulate that the + // cache was flushed for this user by not returning cached data to + // this user that was cached before the timestamp. if (isset($_SESSION['cache_flush']) && is_array($_SESSION['cache_flush'])) { $cache_bins = $_SESSION['cache_flush']; } @@ -262,7 +298,7 @@ class MemCacheDrupal implements DrupalCacheInterface { } } else { - // Register a wildcard flush for current cid + // Register a wildcard flush for current cid. $this->wildcards($cid, TRUE); } } @@ -275,15 +311,24 @@ class MemCacheDrupal implements DrupalCacheInterface { } /** - * Sum of all matching wildcards. Checking any single cache item's flush - * value against this single-value sum tells us whether or not a new wildcard - * flush has affected the cached item. + * Sum of all matching wildcards. + * + * Checking any single cache item's flush value against this single-value sum + * tells us whether or not a new wildcard flush has affected the cached item. + * + * @param string $cid + * The cache id to check. + * + * @return int + * Sum of all matching wildcards for the given cache id. */ - protected function wildcard_flushes($cid) { + protected function wildcardFlushes($cid) { return array_sum($this->wildcards($cid)); } /** + * Retrieves all matching wildcards for the given cache id. + * * Utilize multiget to retrieve all possible wildcard matches, storing * statically so multiple cache requests for the same item on the same page * load doesn't add overhead. @@ -398,17 +443,20 @@ class MemCacheDrupal implements DrupalCacheInterface { /** * Check if a wildcard flush has invalidated the current cached copy. */ - protected function wildcard_valid($cid, $cache) { + protected function wildcardValid($cid, $cache) { // Previously cached content won't have ->flushes defined. We could // force flush, but instead leave this up to the site admin. - $flushes = isset($cache->flushes) ? (int)$cache->flushes : 0; - if ($flushes < (int)$this->wildcard_flushes($cid)) { + $flushes = isset($cache->flushes) ? (int) $cache->flushes : 0; + if ($flushes < (int) $this->wildcardFlushes($cid)) { return FALSE; } return TRUE; } - function isEmpty() { + /** + * Implements DrupalCacheInterface::isEmpty(). + */ + public function isEmpty() { // We do not know so err on the safe side? return FALSE; } @@ -416,7 +464,7 @@ class MemCacheDrupal implements DrupalCacheInterface { /** * Helper function to load locking framework if not already loaded. */ - function lockInit() { + public function lockInit() { // On a cache miss when page_cache_without_database is enabled, we can end // up here without the lock system being initialized. Bootstrap drupal far // enough to load the lock system. @@ -431,7 +479,7 @@ class MemCacheDrupal implements DrupalCacheInterface { * This is used by the tests to verify that the cache object used the correct * settings. */ - function reloadVariables() { + public function reloadVariables() { $this->wildcard_flushes = variable_get('memcache_wildcard_flushes', array()); $this->invalidate = variable_get('memcache_wildcard_invalidate', MEMCACHE_WILDCARD_INVALIDATE); $this->cache_lifetime = variable_get('cache_lifetime', 0); @@ -444,7 +492,7 @@ class MemCacheDrupal implements DrupalCacheInterface { /** * Re-implementation of variable_set() that writes through instead of clearing. */ - function variable_set($name, $value) { + public function variable_set($name, $value) { global $conf; db_merge('variable') diff --git a/memcache.info b/memcache.info index 9a36645183066b81186b96a64dab5d9fa5933708..5d6d493e7f84feaca016506e831591a54bc50e51 100644 --- a/memcache.info +++ b/memcache.info @@ -2,6 +2,7 @@ name = Memcache description = High performance integration with memcache. package = Performance and scalability core = 7.x +files[] = memcache.inc files[] = tests/memcache.test files[] = tests/memcache-session.test files[] = tests/memcache-lock.test diff --git a/memcache.install b/memcache.install index a5e4825af2ffb818918c579dad020e1a409b5516..26b1a1cf88c068fc4f23ac4ca2f75e4c290188fd 100644 --- a/memcache.install +++ b/memcache.install @@ -1,5 +1,42 @@ 'default')); + $memcache = dmemcache_instance(); + foreach ($memcache_servers as $server => $bin) { + if (dmemcache_connect($memcache, $server, FALSE) === FALSE) { + $error = TRUE; + } + else { + dmemcache_close($memcache); + } + } + } + if ($error) { + drupal_set_message(t('There are problems with your Memcache configuration. Please review %readme and visit the Drupal admin !status page for more information.', array('%readme' => 'README.txt', '!status' => l(t('status report'), 'admin/reports/status'))), 'error'); + } +} + /** * Implements hook_requirements(). */ @@ -30,7 +67,7 @@ function memcache_requirements($phase) { if ($extension == 'Memcache') { $requirements['memcache_extension']['value'] = phpversion('memcache') . _memcache_statistics_link(); } - else if ($extension == 'Memcached') { + elseif ($extension == 'Memcached') { $requirements['memcache_extension']['value'] = phpversion('memcached') . _memcache_statistics_link(); } diff --git a/memcache.module b/memcache.module index f70a91bb3accc6d4c1ae1a2b6ea5e0a138a25cdd..4a4bd816be7e4e53383e82f9d0ff3c5aa92a50c9 100644 --- a/memcache.module +++ b/memcache.module @@ -1,34 +1,9 @@ 'default')); - $memcache = dmemcache_instance(); - foreach ($memcache_servers as $server => $bin) { - if (dmemcache_connect($memcache, $server, FALSE) === FALSE) { - $error = TRUE; - } - else { - dmemcache_close($memcache); - } - } - } - if ($error) { - drupal_set_message(t('There are problems with your Memcache configuration. Please review %readme and visit the Drupal admin !status page for more information.', array('%readme' => 'README.txt', '!status' => l('status report', 'admin/reports/status'))), 'error'); - } -} diff --git a/memcache_admin/memcache.js b/memcache_admin/memcache.js index c6b79a0a9ca34bbacaebfba71b77c1fb2e45b20f..c28fbf5ddcb57bd2661adafe590ca906af74f642 100644 --- a/memcache_admin/memcache.js +++ b/memcache_admin/memcache.js @@ -1,7 +1,11 @@ +/** + * @file + * Helper functions for memcache_admin module. + */ // Global Killswitch if (Drupal.jsEnabled) { -$(document).ready(function() { + $(document).ready(function() { $("body").append($("#memcache-devel")); }); } diff --git a/memcache_admin/memcache_admin.install b/memcache_admin/memcache_admin.install index 0f2652e5845702cf55a83b7d19d67ec020892d51..7c5c7118b208c699aba65e4fe9ea881884748183 100644 --- a/memcache_admin/memcache_admin.install +++ b/memcache_admin/memcache_admin.install @@ -1,7 +1,8 @@ part of the HTML - * document. + * @file + * For the collection and display of memcache stats. + * + * This module adds a small .js file to makes sure that the HTML displaying the + * stats is inside of the part of the HTML document. + */ + +/** + * Implements hook_init(). */ function memcache_admin_init() { global $user; if (($user->uid == 0) || strstr($_SERVER['PHP_SELF'], 'update.php') || (isset($_GET['q']) && (in_array($_GET['q'], array('upload/js', 'admin/content/node-settings/rebuild')) || substr($_GET['q'], 0, strlen('system/files')) == 'system/files' || substr($_GET['q'], 0, strlen('batch')) == 'batch' || strstr($_GET['q'], 'autocomplete')))) { - // update.php relies on standard error handler + // update.php relies on standard error handler. } else { if ($user->uid) { - drupal_add_js(drupal_get_path('module', 'memcache_admin'). '/memcache.js'); + drupal_add_js(drupal_get_path('module', 'memcache_admin') . '/memcache.js'); } register_shutdown_function('memcache_admin_shutdown'); } @@ -68,9 +74,9 @@ function memcache_admin_menu() { } } - $items['admin/reports/memcache/'. $cluster] = array( + $items["admin/reports/memcache/$cluster"] = array( 'title' => $cluster, - 'type' => $count == 0 ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + 'type' => $count == 0 ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, 'page callback' => 'memcache_admin_stats', 'page arguments' => array($cluster), 'access arguments' => array('access memcache statistics'), @@ -79,7 +85,7 @@ function memcache_admin_menu() { foreach ($cluster_info['servers'] as $server) { $items["admin/reports/memcache/$cluster/$server"] = array( 'title' => check_plain($server), - 'type' => MENU_CALLBACK, + 'type' => MENU_CALLBACK, 'page callback' => 'memcache_admin_stats_raw', 'page arguments' => array($cluster, $server), 'access arguments' => array('access memcache statistics'), @@ -113,6 +119,9 @@ function memcache_admin_admin_settings() { return system_settings_form($form); } +/** + * Helper function. Returns the bin name. + */ function _memcache_admin_default_bin($bin) { if ($bin == 'default') { return 'cache'; @@ -120,6 +129,9 @@ function _memcache_admin_default_bin($bin) { return $bin; } +/** + * Statistics report: format total and open connections. + */ function _memcache_admin_stats_connections($stats) { return t('!current open of !total total', array('!current' => number_format($stats['curr_connections']), '!total' => number_format($stats['total_connections']))); } @@ -169,7 +181,12 @@ function _memcache_admin_stats_counters($stats) { if (!is_array($stats)) { $stats = array(); } - $stats += array('incr_hits' => 0, 'incr_misses' => 0, 'decr_hits' => 0, 'decr_misses' => 0); + $stats += array( + 'incr_hits' => 0, + 'incr_misses' => 0, + 'decr_hits' => 0, + 'decr_misses' => 0, + ); return t('!incr increments, !decr decrements', array('!incr' => number_format($stats['incr_hits'] + $stats['incr_misses']), '!decr' => number_format($stats['decr_hits'] + $stats['decr_misses']))); } @@ -183,7 +200,7 @@ function _memcache_admin_stats_transfer($stats) { else { $written = $stats['bytes_read'] / $stats['bytes_written'] * 100; } - return t('!to:!from (!written% to cache)', array('!to' => format_size((int)$stats['bytes_read']), '!from' => format_size((int)$stats['bytes_written']), '!written' => number_format($written, 2))); + return t('!to:!from (!written% to cache)', array('!to' => format_size((int) $stats['bytes_read']), '!from' => format_size((int) $stats['bytes_written']), '!written' => number_format($written, 2))); } /** @@ -233,9 +250,10 @@ function memcache_admin_bin_mapping($bin = 'cache') { } /** - * Memcache Stats page + * Callback for the Memcache Stats page. * * @return string + * The page output. */ function memcache_admin_stats($bin = 'default') { $bin = memcache_admin_bin_mapping($bin); @@ -344,7 +362,11 @@ function memcache_admin_stats($bin = 'default') { $data['memory_evictions']), ), ); - $output = theme('memcache_admin_stats_table', array('bin' => $bin, 'servers' => $servers, 'report' => $report)); + $output = theme('memcache_admin_stats_table', array( + 'bin' => $bin, + 'servers' => $servers, + 'report' => $report, + )); } else { $output = ''; @@ -354,29 +376,53 @@ function memcache_admin_stats($bin = 'default') { return $output; } +/** + * Callback for the server statistics page. + */ function memcache_admin_stats_raw($bin, $server, $type = 'default') { $cluster = memcache_admin_bin_mapping($bin); - $slab = (int)arg(7); + $slab = (int) arg(7); if (arg(6) == 'cachedump' && !empty($slab) && user_access('access slab cachedump')) { $stats = dmemcache_stats($cluster, arg(7), FALSE); } else { $stats = dmemcache_stats($cluster, $type, FALSE); } - $breadcrumbs = array(l(t('Home'), NULL), l(t('Administer'), 'admin'), l(t('Reports'), 'admin/reports'), l(t('Memcache'), 'admin/reports/memcache'), l(t($bin), "admin/reports/memcache/$bin")); + $breadcrumbs = array( + l(t('Home'), NULL), + l(t('Administer'), 'admin'), + l(t('Reports'), 'admin/reports'), + l(t('Memcache'), 'admin/reports/memcache'), + l(t($bin), "admin/reports/memcache/$bin"), + ); if ($type == 'slabs' && arg(6) == 'cachedump' && user_access('access slab cachedump')) { $breadcrumbs[] = l($server, "admin/reports/memcache/$bin/$server"); - $breadcrumbs[] = l('slabs', "admin/reports/memcache/$bin/$server/$type"); + $breadcrumbs[] = l(t('slabs'), "admin/reports/memcache/$bin/$server/$type"); } drupal_set_breadcrumb($breadcrumbs); if (isset($stats[$cluster][$server]) && is_array($stats[$cluster][$server]) && count($stats[$cluster][$server])) { - $output = theme('memcache_admin_stats_raw_table', array('cluster' => $cluster, 'server' => $server, 'stats' => $stats[$cluster][$server], 'type' => $type)); + $output = theme('memcache_admin_stats_raw_table', array( + 'cluster' => $cluster, + 'server' => $server, + 'stats' => $stats[$cluster][$server], + 'type' => $type, + )); } elseif ($type == 'slabs' && is_array($stats[$cluster]) && count($stats[$cluster])) { - $output = theme('memcache_admin_stats_raw_table', array('cluster' => $cluster, 'server' => $server, 'stats' => $stats[$cluster], 'type' => $type)); + $output = theme('memcache_admin_stats_raw_table', array( + 'cluster' => $cluster, + 'server' => $server, + 'stats' => $stats[$cluster], + 'type' => $type, + )); } else { - $output = theme('memcache_admin_stats_raw_table', array('cluster' => $cluster, 'server' => $server, 'stats' => array(), 'type' => $type)); + $output = theme('memcache_admin_stats_raw_table', array( + 'cluster' => $cluster, + 'server' => $server, + 'stats' => array(), + 'type' => $type, + )); drupal_set_message(t('No @type statistics for this bin.', array('@type' => $type))); } return $output; @@ -388,16 +434,25 @@ function memcache_admin_stats_raw($bin, $server, $type = 'default') { function memcache_admin_theme() { return array( 'memcache_admin_stats_table' => array( - 'variables' => array('bin' => NULL, 'servers' => NULL, 'report' => NULL), + 'variables' => array( + 'bin' => NULL, + 'servers' => NULL, + 'report' => NULL, + ), ), 'memcache_admin_stats_raw_table' => array( - 'variables' => array('bin' => NULL, 'server' => NULL, 'stats' => NULL, 'type' => NULL), - ) + 'variables' => array( + 'bin' => NULL, + 'server' => NULL, + 'stats' => NULL, + 'type' => NULL, + ), + ), ); } /** - * Theme function for rendering the output from memcache_admin_stats + * Theme function for rendering the output from memcache_admin_stats. */ function theme_memcache_admin_stats_table($variables) { $bin = $variables['bin']; @@ -422,6 +477,9 @@ function theme_memcache_admin_stats_table($variables) { return $output; } +/** + * Returns an array of available statistics types. + */ function memcache_admin_stats_types($bin) { module_load_include('inc', 'memcache', 'dmemcache'); if ($mc = dmemcache_object($bin)) { @@ -442,6 +500,9 @@ function memcache_admin_stats_types($bin) { } } +/** + * Theme function to produce a table of statistics. + */ function theme_memcache_admin_stats_raw_table($variables) { $cluster = $variables['cluster']; $server = $variables['server']; @@ -450,14 +511,14 @@ function theme_memcache_admin_stats_raw_table($variables) { $memcache_bins = variable_get('memcache_bins', array()); $bin = isset($memcache_bins[$cluster]) ? $memcache_bins[$cluster] : 'default'; - // Provide navigation for the various memcache stats types + // Provide navigation for the various memcache stats types. if (count(memcache_admin_stats_types($bin)) > 1) { foreach (memcache_admin_stats_types($bin) as $type) { if ($current_type == $type) { - $links[] = '' . l(t($type), "admin/reports/memcache/$bin/$server/". ($type == 'default' ? '' : $type)) .''; + $links[] = '' . l(t($type), "admin/reports/memcache/$bin/$server/" . ($type == 'default' ? '' : $type)) . ''; } else { - $links[] = l(t($type), "admin/reports/memcache/$bin/$server/". ($type == 'default' ? '' : $type)); + $links[] = l(t($type), "admin/reports/memcache/$bin/$server/" . ($type == 'default' ? '' : $type)); } } } @@ -471,7 +532,7 @@ function theme_memcache_admin_stats_raw_table($variables) { $stats = $stats['items']; } foreach ($stats as $key => $value) { - // Add navigation for getting a cachedump of individual slabs + // Add navigation for getting a cachedump of individual slabs. if (($current_type == 'slabs' || $current_type == 'items') && is_int($key) && user_access('access slab cachedump')) { $key = l($key, "admin/reports/memcache/$bin/$server/slabs/cachedump/$key"); } @@ -483,7 +544,7 @@ function theme_memcache_admin_stats_raw_table($variables) { $k = t('Size'); $v = format_size($v); } - else if ($current_type == 'slabs' && user_access('access slab cachedump') && arg(6) == 'cachedump' && $k == 1) { + elseif ($current_type == 'slabs' && user_access('access slab cachedump') && arg(6) == 'cachedump' && $k == 1) { $k = t('Expire'); $full_stats = dmemcache_stats($cluster, 'default'); $infinite = $full_stats[$cluster][$server]['time'] - $full_stats[$cluster][$server]['uptime']; @@ -495,7 +556,7 @@ function theme_memcache_admin_stats_raw_table($variables) { } } $rs[] = array(check_plain($k), check_plain($v)); - } + } $rows[] = array($key, theme('table', array('rows' => $rs))); } else { @@ -507,10 +568,13 @@ function theme_memcache_admin_stats_raw_table($variables) { } /** - * Retrieve the cluster for any given bin + * Retrieve the bin for any given cluster. + * + * @param string $cluster + * Cluster ID * - * @param string $cluster - Cluster ID * @return string + * The name of the bin. */ function _memcache_admin_get_bin_for_cluster($cluster) { static $cluster_map = array(); @@ -528,11 +592,14 @@ function _memcache_admin_get_bin_for_cluster($cluster) { return $cluster_map[$cluster]; } +/** + * Helper function. Calculate a percentage. + */ function _memcache_admin_stats_percent($a, $b) { if ($a == 0) { return 0; } - else if ($b == 0) { + elseif ($b == 0) { return 100; } else { @@ -541,8 +608,9 @@ function _memcache_admin_stats_percent($a, $b) { } /** - * See memcache_admin_init() which registers this function as a shutdown function. - * Displays memcache stats in the footer. + * Displays memcache stats in the footer. This is run as a shutdown function. + * + * @see memcache_admin_init() */ function memcache_admin_shutdown() { global $_dmemcache_stats; @@ -559,7 +627,16 @@ function memcache_admin_shutdown() { if (function_exists('drupal_get_http_header')) { $header = drupal_get_http_header('content-type'); if ($header) { - $formats = array('xml', 'javascript', 'json', 'plain', 'image', 'application', 'csv', 'x-comma-separated-values'); + $formats = array( + 'xml', + 'javascript', + 'json', + 'plain', + 'image', + 'application', + 'csv', + 'x-comma-separated-values', + ); foreach ($formats as $format) { if (strstr($header, $format)) { return; @@ -579,8 +656,15 @@ function memcache_admin_shutdown() { $_dmemcache_stats['ops'][$row][2] = number_format($stats[2]) . " ($hits%)"; $_dmemcache_stats['ops'][$row][3] = number_format($stats[3]) . " ($misses%)"; } - $variables = array('header' => array(t('operation'), t('total ms'), t('total hits'), t('total misses')), - 'rows' => $_dmemcache_stats['ops']); + $variables = array( + 'header' => array( + t('operation'), + t('total ms'), + t('total hits'), + t('total misses'), + ), + 'rows' => $_dmemcache_stats['ops'], + ); $output .= theme('table', $variables); } if (!empty($_dmemcache_stats['all'])) { @@ -590,14 +674,23 @@ function memcache_admin_shutdown() { $_dmemcache_stats['all'][$row][3] = check_plain($stats[3]); } - $variables = array('header' => array(t('ms'), t('operation'), t('bin'), t('key'), t('status')), - 'rows' => $_dmemcache_stats['all']); + $variables = array( + 'header' => array( + t('ms'), + t('operation'), + t('bin'), + t('key'), + t('status'), + ), + 'rows' => $_dmemcache_stats['all'], + ); $output .= theme('table', $variables); } if (!empty($output)) { - // this makes sure all of the HTML is within the even though this