Commit 49b51438 authored by mikeytown2's avatar mikeytown2

Issue #2562143 by mikeytonw2: Fix some issues with the microcache wrapper.

parent 37db4beb
......@@ -3542,7 +3542,7 @@ function httprl_call_user_func_array_async($callback, array $param_arr) {
* The parameters to be passed to the callback, as an indexed array.
* @param array $options
* An associative array with the keys cache_lifetime_min, cache_lifetime_max,
* and bin.
* bin, lock_timeout, and return_null_cache_miss.
*
* @return mixed
* Array of results.
......@@ -3557,19 +3557,41 @@ function httprl_call_user_func_array_cache($callback, array $param_arr = array()
'bin' => 'cache',
// Lock timeout.
'lock_timeout' => 30.0,
// Return NULL if cache miss.
'return_null_cache_miss' => FALSE,
);
// The cache id for this call.
$cid = __FUNCTION__ . ':' . drupal_hash_base64(serialize(array($callback, $param_arr)));
if (is_string($callback)) {
$cid = __FUNCTION__ . ':' . $callback . ':' . drupal_hash_base64(serialize(array($param_arr)));
}
else {
$cid = __FUNCTION__ . ':' . drupal_hash_base64(serialize(array($callback, $param_arr)));
}
$cache = cache_get($cid);
// Don't use the cache if it's not there or the cached item is older than
// the max cache lifetime.
if (!isset($cache->data) || $cache->created < REQUEST_TIME - $options['cache_lifetime_max']) {
$cache = new stdClass();
// Run the callback.
$cache->data = call_user_func_array($callback, $param_arr);
// Save the cached data.
cache_set($cid, $cache->data, $options['bin'], $options['cache_lifetime_max'] + time());
if (empty($options['return_null_cache_miss']) && (!isset($cache->data) || $cache->created < REQUEST_TIME - $options['cache_lifetime_max'])) {
if (httprl_acquire_headless_lock($cid . ':run_function', $options['lock_timeout'])) {
$cache = new stdClass();
// Run the callback.
$cache->data = call_user_func_array($callback, $param_arr);
// Save the cached data.
cache_set($cid, $cache->data, $options['bin'], $options['cache_lifetime_max'] + time());
// Release lock.
httprl_lock_release($cid . ':run_function');
}
else {
lock_wait($cid . ':run_function', $options['lock_timeout']);
$cache = cache_get($cid);
if (!isset($cache->data)) {
$cache = new stdClass();
// Run the callback.
$cache->data = call_user_func_array($callback, $param_arr);
// Save the cached data.
cache_set($cid, $cache->data, $options['bin'], $options['cache_lifetime_max'] + time());
}
}
// Release the lock if the cache lifetime is 0.
if ($options['cache_lifetime_max'] == 0) {
httprl_lock_release($cid);
......@@ -3578,17 +3600,20 @@ function httprl_call_user_func_array_cache($callback, array $param_arr = array()
else {
// Regenerate if cache is older than min cache lifetime and no one else is
// doing the same thing.
if ( $cache->created < REQUEST_TIME - $options['cache_lifetime_min']
if (empty($cache) || $cache->created < REQUEST_TIME - $options['cache_lifetime_min']
&& lock_may_be_available($cid . ':run_function')
&& httprl_acquire_headless_lock($cid, $options['lock_timeout'])
) {
// Get all function arguments.
$args = func_get_args();
$args = array($callback, $param_arr, $options);
// Set max to zero so this gets regenerated in the background.
$args[2]['cache_lifetime_max'] = 0;
// Also do not skip on a cache miss.
$args[2]['return_null_cache_miss'] = FALSE;
// Call this function again in another process with max lifetime set to
// zero.
httprl_call_user_func_array_async(__FUNCTION__, $args);
}
}
return $cache->data;
return isset($cache->data) ? $cache->data : NULL;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment