class BackendChain

Defines a chained cache implementation for combining multiple cache backends.

Can be used to combine two or more backends together to behave as if they were a single backend.

For example a slower, persistent storage engine could be combined with a faster, volatile storage engine. When retrieving items from cache, they will be fetched from the volatile backend first, only falling back to the persistent backend if an item is not available. An item not present in the volatile backend but found in the persistent one will be propagated back up to ensure fast retrieval on the next request. On cache sets and deletes, both backends will be invoked to ensure consistency.

Hierarchy

Expanded class hierarchy of BackendChain

2 files declare their use of BackendChain
BackendChainImplementationUnitTest.php in drupal/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainImplementationUnitTest.php
Definition of Drupal\system\Tests\Cache\BackendChainImplementationUnitTest.
BackendChainUnitTest.php in drupal/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainUnitTest.php
Definition of Drupal\system\Tests\Cache\BackendChainUnitTest.

File

drupal/core/lib/Drupal/Core/Cache/BackendChain.php, line 24
Definition of Drupal\Core\Cache\BackendChain.

Namespace

Drupal\Core\Cache
View source
class BackendChain implements CacheBackendInterface {

  /**
   * Ordered list of CacheBackendInterface instances.
   *
   * @var array
   */
  protected $backends = array();

  /**
   * Constructs a DatabaseBackend object.
   *
   * @param string $bin
   *   The cache bin for which the object is created.
   */
  public function __construct($bin) {
  }

  /**
   * Appends a cache backend to the cache chain.
   *
   * @param CacheBackendInterface $backend
   *   The cache backend to be appended to the cache chain.
   *
   * @return Drupal\Core\Cache\BackendChain
   *   The called object.
   */
  public function appendBackend(CacheBackendInterface $backend) {
    $this->backends[] = $backend;
    return $this;
  }

  /**
   * Prepends a cache backend to the cache chain.
   *
   * @param CacheBackendInterface $backend
   *   The backend to be prepended to the cache chain.
   *
   * @return Drupal\Core\Cache\BackendChain
   *   The called object.
   */
  public function prependBackend(CacheBackendInterface $backend) {
    array_unshift($this->backends, $backend);
    return $this;
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::get().
   */
  public function get($cid, $allow_invalid = FALSE) {
    foreach ($this->backends as $index => $backend) {
      if (($return = $backend
        ->get($cid, $allow_invalid)) !== FALSE) {

        // We found a result, propagate it to all missed backends.
        if ($index > 0) {
          for ($i = $index - 1; 0 <= $i; --$i) {
            $this->backends[$i]
              ->set($cid, $return->data, $return->expire, $return->tags);
          }
        }
        return $return;
      }
    }
    return FALSE;
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::getMultiple().
   */
  public function getMultiple(&$cids, $allow_invalid = FALSE) {
    $return = array();
    foreach ($this->backends as $index => $backend) {
      $items = $backend
        ->getMultiple($cids, $allow_invalid);

      // Propagate the values that could be retrieved from the current cache
      // backend to all missed backends.
      if ($index > 0 && !empty($items)) {
        for ($i = $index - 1; 0 <= $i; --$i) {
          foreach ($items as $cached) {
            $this->backends[$i]
              ->set($cached->cid, $cached->data, $cached->expire, $cached->tags);
          }
        }
      }

      // Append the values to the previously retrieved ones.
      $return += $items;
      if (empty($cids)) {

        // No need to go further if we don't have any cid to fetch left.
        break;
      }
    }
    return $return;
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::set().
   */
  public function set($cid, $data, $expire = CacheBackendInterface::CACHE_PERMANENT, array $tags = array()) {
    foreach ($this->backends as $backend) {
      $backend
        ->set($cid, $data, $expire, $tags);
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::delete().
   */
  public function delete($cid) {
    foreach ($this->backends as $backend) {
      $backend
        ->delete($cid);
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::deleteMultiple().
   */
  public function deleteMultiple(array $cids) {
    foreach ($this->backends as $backend) {
      $backend
        ->deleteMultiple($cids);
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::deleteTags().
   */
  public function deleteTags(array $tags) {
    foreach ($this->backends as $backend) {
      $backend
        ->deleteTags($tags);
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::deleteAll().
   */
  public function deleteAll() {
    foreach ($this->backends as $backend) {
      $backend
        ->deleteAll();
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::expire().
   */
  public function deleteExpired() {
    foreach ($this->backends as $backend) {
      $backend
        ->deleteExpired();
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::invalidate().
   */
  public function invalidate($cid) {
    foreach ($this->backends as $backend) {
      $backend
        ->invalidate($cid);
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple().
   */
  public function invalidateMultiple(array $cids) {
    foreach ($this->backends as $backend) {
      $backend
        ->invalidateMultiple($cids);
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::invalidateTags().
   */
  public function invalidateTags(array $tags) {
    foreach ($this->backends as $backend) {
      $backend
        ->invalidateTags($tags);
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::invalidateAll().
   */
  public function invalidateAll() {
    foreach ($this->backends as $backend) {
      $backend
        ->invalidateAll();
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::garbageCollection().
   */
  public function garbageCollection() {
    foreach ($this->backends as $backend) {
      $backend
        ->garbageCollection();
    }
  }

  /**
   * Implements Drupal\Core\Cache\CacheBackendInterface::isEmpty().
   */
  public function isEmpty() {
    foreach ($this->backends as $backend) {
      if (!$backend
        ->isEmpty()) {
        return FALSE;
      }
    }
    return TRUE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BackendChain::$backends protected property Ordered list of CacheBackendInterface instances.
BackendChain::appendBackend public function Appends a cache backend to the cache chain.
BackendChain::delete public function Implements Drupal\Core\Cache\CacheBackendInterface::delete(). Overrides CacheBackendInterface::delete
BackendChain::deleteAll public function Implements Drupal\Core\Cache\CacheBackendInterface::deleteAll(). Overrides CacheBackendInterface::deleteAll
BackendChain::deleteExpired public function Implements Drupal\Core\Cache\CacheBackendInterface::expire(). Overrides CacheBackendInterface::deleteExpired
BackendChain::deleteMultiple public function Implements Drupal\Core\Cache\CacheBackendInterface::deleteMultiple(). Overrides CacheBackendInterface::deleteMultiple
BackendChain::deleteTags public function Implements Drupal\Core\Cache\CacheBackendInterface::deleteTags(). Overrides CacheBackendInterface::deleteTags
BackendChain::garbageCollection public function Implements Drupal\Core\Cache\CacheBackendInterface::garbageCollection(). Overrides CacheBackendInterface::garbageCollection
BackendChain::get public function Implements Drupal\Core\Cache\CacheBackendInterface::get(). Overrides CacheBackendInterface::get
BackendChain::getMultiple public function Implements Drupal\Core\Cache\CacheBackendInterface::getMultiple(). Overrides CacheBackendInterface::getMultiple
BackendChain::invalidate public function Implements Drupal\Core\Cache\CacheBackendInterface::invalidate(). Overrides CacheBackendInterface::invalidate
BackendChain::invalidateAll public function Implements Drupal\Core\Cache\CacheBackendInterface::invalidateAll(). Overrides CacheBackendInterface::invalidateAll
BackendChain::invalidateMultiple public function Implements Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple(). Overrides CacheBackendInterface::invalidateMultiple
BackendChain::invalidateTags public function Implements Drupal\Core\Cache\CacheBackendInterface::invalidateTags(). Overrides CacheBackendInterface::invalidateTags
BackendChain::isEmpty public function Implements Drupal\Core\Cache\CacheBackendInterface::isEmpty(). Overrides CacheBackendInterface::isEmpty
BackendChain::prependBackend public function Prepends a cache backend to the cache chain.
BackendChain::set public function Implements Drupal\Core\Cache\CacheBackendInterface::set(). Overrides CacheBackendInterface::set
BackendChain::__construct public function Constructs a DatabaseBackend object.
CacheBackendInterface::CACHE_PERMANENT constant Indicates that the item should never be removed unless explicitly deleted.