function cache_get in Memcache API and Integration 6
Same name in this branch
- 6 memcache.db.inc \cache_get()
- 6 memcache.inc \cache_get()
Same name and namespace in other branches
- 5.2 memcache.db.inc \cache_get()
- 5.2 memcache.inc \cache_get()
- 5 memcache.db.inc \cache_get()
- 5 memcache.inc \cache_get()
Return data from the persistent cache.
Data may be stored as either plain text or as serialized data. cache_get() will automatically return unserialized objects and arrays.
Parameters
$cid: The cache ID of the data to retrieve.
$table: The table $table to store the data in. Valid core values are 'cache_filter', 'cache_menu', 'cache_page', or 'cache' for the default cache.
6 calls to cache_get()
- MemCacheSavingCase::checkVariable in tests/
memcache.test - MemCacheSavingCase::testObject in tests/
memcache.test - Test the saving and restoring of an object.
- MemcacheTestCase::assertCacheRemoved in tests/
memcache.test - Assert or a cache entry has been removed.
- MemcacheTestCase::checkCacheExists in tests/
memcache.test - Check whether or not a cache entry exists.
- memcache_requirements in ./
memcache.install - Implements hook_requirements().
File
- ./
memcache.inc, line 33
Code
function cache_get($cid, $table = 'cache') {
// Handle excluded bins first.
$bins = variable_get('memcache_bins', array());
if (!is_null($table) && isset($bins[$table]) && $bins[$table] == 'database') {
return _cache_get($cid, $table);
}
// Clean-up the per-user cache expiration session data, so that the session
// handler can properly clean-up the session data for anonymous users.
if (isset($_SESSION['cache_flush'])) {
$expire = $_SERVER['REQUEST_TIME'] - variable_get('cache_lifetime', 0);
foreach ($_SESSION['cache_flush'] as $bin => $timestamp) {
if ($timestamp < $expire) {
unset($_SESSION['cache_flush'][$bin]);
}
}
if (!$_SESSION['cache_flush']) {
unset($_SESSION['cache_flush']);
}
}
// Retrieve the item from the cache.
$cache = dmemcache_get($cid, $table);
// Set up common variables.
$cache_flush = variable_get("cache_flush_{$table}", 0);
$cache_content_flush = variable_get("cache_content_flush_{$table}", 0);
$cache_tables = isset($_SESSION['cache_flush']) ? $_SESSION['cache_flush'] : NULL;
$cache_lifetime = variable_get('cache_lifetime', 0);
$wildcard_flushes = variable_get('memcache_wildcard_flushes', array());
$wildcard_invalidate = variable_get('memcache_wildcard_invalidate', MEMCACHE_WILDCARD_INVALIDATE);
if (is_object($cache)) {
// 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
// use of CACHE_TEMPORARY which does not map well to memcache.
// @see http://drupal.org/node/534092
if (variable_get('memcache_stampede_protection', FALSE) && memcache_stampede_protected($cid, $table)) {
// The process that acquires the lock will get a cache miss, all
// others will get a cache hit.
if (lock_acquire("memcache_{$cid}:{$table}", variable_get('memcache_stampede_semaphore', 15))) {
$cache = FALSE;
}
}
else {
$cache = FALSE;
}
}
elseif ($cache->created <= $cache_flush) {
$cache = FALSE;
}
elseif ($cache->expire != CACHE_PERMANENT && $cache->created + $cache_lifetime <= $cache_content_flush) {
$cache = FALSE;
}
elseif ($cache->expire != CACHE_PERMANENT && is_array($cache_tables) && isset($cache_tables[$table]) && $cache_tables[$table] >= $cache->created) {
// Cache item expired, return FALSE.
$cache = FALSE;
}
else {
$flushes = isset($cache->flushes) ? (int) $cache->flushes : 0;
$recorded_flushes = memcache_wildcard_flushes($cid, $table);
if ($flushes < $recorded_flushes) {
$cache = FALSE;
}
// If wildcards are cleared by a partial memcache flush or eviction
// then it is possible for $cache->flushes to be greater than the return
// of memcache_wildcard_flushes().
if ($flushes > $recorded_flushes) {
// Delete the cache item entirely, it will be set again with the correct
// number of flushes.
dmemcache_delete($cid, $table);
$cache = FALSE;
}
}
}
else {
$cache = FALSE;
}
// On cache misses, attempt to avoid stampedes when the
// memcache_stampede_protection variable is enabled.
if (!$cache) {
if (variable_get('memcache_stampede_protection', FALSE) && memcache_stampede_protected($cid, $table) && !lock_acquire("memcache_{$cid}:{$table}", variable_get('memcache_stampede_semaphore', 15))) {
// Prevent any single request from waiting more than three times due to
// stampede protection. By default this is a maximum total wait of 15
// seconds. This accounts for two possibilities - a cache and lock miss
// more than once for the same item. Or a cache and lock miss for
// different items during the same request.
// @todo: it would be better to base this on time waited rather than
// number of waits, but the lock API does not currently provide this
// information. Currently the limit will kick in for three waits of 25ms
// or three waits of 5000ms.
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 sempahore value by 3 (5 seconds).
lock_wait("memcache_{$cid}:{$table}", variable_get('memcache_stampede_wait_time', 5));
return cache_get($cid, $table);
}
}
}
// Clean up $_SESSION['cache_flush'] variable array if it is older than
// the minimum cache lifetime, since after that the $cache_flush variable
// will take over.
if (is_array($cache_tables) && !empty($cache_tables) && $cache_lifetime) {
// Expire the $_SESSION['cache_flush'] variable array if it is older than
// the minimum cache lifetime, since after that the $cache_flush variable
// will take over.
if (max($cache_tables) < $_SERVER['REQUEST_TIME'] - $cache_lifetime) {
unset($_SESSION['cache_flush']);
$cache_tables = NULL;
}
}
return $cache;
}