You are here

function httprl_call_user_func_array_cache in HTTP Parallel Request & Threading Library 7

Same name and namespace in other branches
  1. 6 httprl.module \httprl_call_user_func_array_cache()

Cache a function; regenerate return value in the background.

Parameters

callable $callback: The callable to be called.

array $param_arr: The parameters to be passed to the callback, as an indexed array.

array $options: An associative array with the keys cache_lifetime_min, cache_lifetime_max, bin, lock_timeout, and return_null_cache_miss.

Return value

mixed Array of results.

1 string reference to 'httprl_call_user_func_array_cache'
_httprl_run_cache_functions in ./httprl.module
Cache function helper. Runs the array through the cache function.

File

./httprl.module, line 3646
HTTP Parallel Request Library module.

Code

function httprl_call_user_func_array_cache($callback, array $param_arr = array(), array $options = array()) {
  $options += array(
    // How long to wait until regenerating this cached value.
    'cache_lifetime_min' => 0,
    // How long the cache can still be used; 3600 = 1 hour.
    'cache_lifetime_max' => 3600,
    // What cache bin to use.
    'bin' => 'cache',
    // Lock timeout.
    'lock_timeout' => 30.0,
    // Return NULL if cache miss.
    'return_null_cache_miss' => FALSE,
  );

  // The cache id for this call.
  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, $options['bin']);

  // Don't use the cache if it's not there or the cached item is older than
  // the max cache lifetime.
  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);
    }
  }
  else {

    // Regenerate if cache is older than min cache lifetime and no one else is
    // doing the same thing.
    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'])) {

      // Set max to zero so this gets regenerated in the background.
      // Also do not skip on a cache miss.
      $options['cache_lifetime_max'] = 0;
      $options['return_null_cache_miss'] = FALSE;

      // Get all function arguments.
      $args = array(
        $callback,
        $param_arr,
        $options,
      );
      if (!httprl_is_background_callback_capable()) {

        // Call this function again in a shutdown function.
        _httprl_run_functions_once_on_shutdown_array_cache($args);
      }
      else {

        // Call this function again in another process.
        httprl_call_user_func_array_async('httprl_call_user_func_array_cache', $args);
      }
    }
  }
  return isset($cache->data) ? $cache->data : NULL;
}