You are here

class RiakCache in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php \Doctrine\Common\Cache\RiakCache

Riak cache provider.

@link www.doctrine-project.org @since 1.1 @author Guilherme Blanco <guilhermeblanco@hotmail.com>

Hierarchy

Expanded class hierarchy of RiakCache

1 file declares its use of RiakCache
RiakCacheTest.php in vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/RiakCacheTest.php

File

vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php, line 35

Namespace

Doctrine\Common\Cache
View source
class RiakCache extends CacheProvider {
  const EXPIRES_HEADER = 'X-Riak-Meta-Expires';

  /**
   * @var \Riak\Bucket
   */
  private $bucket;

  /**
   * Sets the riak bucket instance to use.
   *
   * @param \Riak\Bucket $bucket
   */
  public function __construct(Bucket $bucket) {
    $this->bucket = $bucket;
  }

  /**
   * {@inheritdoc}
   */
  protected function doFetch($id) {
    try {
      $response = $this->bucket
        ->get($id);

      // No objects found
      if (!$response
        ->hasObject()) {
        return false;
      }

      // Check for attempted siblings
      $object = $response
        ->hasSiblings() ? $this
        ->resolveConflict($id, $response
        ->getVClock(), $response
        ->getObjectList()) : $response
        ->getFirstObject();

      // Check for expired object
      if ($this
        ->isExpired($object)) {
        $this->bucket
          ->delete($object);
        return false;
      }
      return unserialize($object
        ->getContent());
    } catch (Exception\RiakException $e) {

      // Covers:
      // - Riak\ConnectionException
      // - Riak\CommunicationException
      // - Riak\UnexpectedResponseException
      // - Riak\NotFoundException
    }
    return false;
  }

  /**
   * {@inheritdoc}
   */
  protected function doContains($id) {
    try {

      // We only need the HEAD, not the entire object
      $input = new Input\GetInput();
      $input
        ->setReturnHead(true);
      $response = $this->bucket
        ->get($id, $input);

      // No objects found
      if (!$response
        ->hasObject()) {
        return false;
      }
      $object = $response
        ->getFirstObject();

      // Check for expired object
      if ($this
        ->isExpired($object)) {
        $this->bucket
          ->delete($object);
        return false;
      }
      return true;
    } catch (Exception\RiakException $e) {

      // Do nothing
    }
    return false;
  }

  /**
   * {@inheritdoc}
   */
  protected function doSave($id, $data, $lifeTime = 0) {
    try {
      $object = new Object($id);
      $object
        ->setContent(serialize($data));
      if ($lifeTime > 0) {
        $object
          ->addMetadata(self::EXPIRES_HEADER, (string) (time() + $lifeTime));
      }
      $this->bucket
        ->put($object);
      return true;
    } catch (Exception\RiakException $e) {

      // Do nothing
    }
    return false;
  }

  /**
   * {@inheritdoc}
   */
  protected function doDelete($id) {
    try {
      $this->bucket
        ->delete($id);
      return true;
    } catch (Exception\BadArgumentsException $e) {

      // Key did not exist on cluster already
    } catch (Exception\RiakException $e) {

      // Covers:
      // - Riak\Exception\ConnectionException
      // - Riak\Exception\CommunicationException
      // - Riak\Exception\UnexpectedResponseException
    }
    return false;
  }

  /**
   * {@inheritdoc}
   */
  protected function doFlush() {
    try {
      $keyList = $this->bucket
        ->getKeyList();
      foreach ($keyList as $key) {
        $this->bucket
          ->delete($key);
      }
      return true;
    } catch (Exception\RiakException $e) {

      // Do nothing
    }
    return false;
  }

  /**
   * {@inheritdoc}
   */
  protected function doGetStats() {

    // Only exposed through HTTP stats API, not Protocol Buffers API
    return null;
  }

  /**
   * Check if a given Riak Object have expired.
   *
   * @param \Riak\Object $object
   *
   * @return boolean
   */
  private function isExpired(object $object) {
    $metadataMap = $object
      ->getMetadataMap();
    return isset($metadataMap[self::EXPIRES_HEADER]) && $metadataMap[self::EXPIRES_HEADER] < time();
  }

  /**
   * On-read conflict resolution. Applied approach here is last write wins.
   * Specific needs may override this method to apply alternate conflict resolutions.
   *
   * {@internal Riak does not attempt to resolve a write conflict, and store
   * it as sibling of conflicted one. By following this approach, it is up to
   * the next read to resolve the conflict. When this happens, your fetched
   * object will have a list of siblings (read as a list of objects).
   * In our specific case, we do not care about the intermediate ones since
   * they are all the same read from storage, and we do apply a last sibling
   * (last write) wins logic.
   * If by any means our resolution generates another conflict, it'll up to
   * next read to properly solve it.}
   *
   * @param string $id
   * @param string $vClock
   * @param array  $objectList
   *
   * @return \Riak\Object
   */
  protected function resolveConflict($id, $vClock, array $objectList) {

    // Our approach here is last-write wins
    $winner = $objectList[count($objectList)];
    $putInput = new Input\PutInput();
    $putInput
      ->setVClock($vClock);
    $mergedObject = new Object($id);
    $mergedObject
      ->setContent($winner
      ->getContent());
    $this->bucket
      ->put($mergedObject, $putInput);
    return $mergedObject;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Cache::STATS_HITS constant
Cache::STATS_MEMORY_AVAILABLE constant
Cache::STATS_MEMORY_AVAILIABLE constant Only for backward compatibility (may be removed in next major release)
Cache::STATS_MEMORY_USAGE constant
Cache::STATS_MISSES constant
Cache::STATS_UPTIME constant
CacheProvider::$namespace private property The namespace to prefix all cache ids with.
CacheProvider::$namespaceVersion private property The namespace version.
CacheProvider::contains public function Tests if an entry exists in the cache. Overrides Cache::contains
CacheProvider::delete public function Deletes a cache entry. Overrides Cache::delete
CacheProvider::deleteAll public function Deletes all cache entries in the current cache namespace. Overrides ClearableCache::deleteAll
CacheProvider::DOCTRINE_NAMESPACE_CACHEKEY constant
CacheProvider::doFetchMultiple protected function Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it. 4
CacheProvider::fetch public function Fetches an entry from the cache. Overrides Cache::fetch
CacheProvider::fetchMultiple public function Returns an associative array of values for keys is found in cache. Overrides MultiGetCache::fetchMultiple
CacheProvider::flushAll public function Flushes all cache entries, globally. Overrides FlushableCache::flushAll
CacheProvider::getNamespace public function Retrieves the namespace that prefixes all cache ids.
CacheProvider::getNamespaceCacheKey private function Returns the namespace cache key.
CacheProvider::getNamespacedId private function Prefixes the passed id with the configured namespace value.
CacheProvider::getNamespaceVersion private function Returns the namespace version.
CacheProvider::getStats public function Retrieves cached information from the data store. Overrides Cache::getStats
CacheProvider::save public function Puts data into the cache. Overrides Cache::save
CacheProvider::setNamespace public function Sets the namespace to prefix all cache ids with. 1
RiakCache::$bucket private property
RiakCache::doContains protected function Tests if an entry exists in the cache. Overrides CacheProvider::doContains
RiakCache::doDelete protected function Deletes a cache entry. Overrides CacheProvider::doDelete
RiakCache::doFetch protected function Fetches an entry from the cache. Overrides CacheProvider::doFetch
RiakCache::doFlush protected function Flushes all cache entries. Overrides CacheProvider::doFlush
RiakCache::doGetStats protected function Retrieves cached information from the data store. Overrides CacheProvider::doGetStats
RiakCache::doSave protected function Puts data into the cache. Overrides CacheProvider::doSave
RiakCache::EXPIRES_HEADER constant
RiakCache::isExpired private function Check if a given Riak Object have expired.
RiakCache::resolveConflict protected function On-read conflict resolution. Applied approach here is last write wins. Specific needs may override this method to apply alternate conflict resolutions.
RiakCache::__construct public function Sets the riak bucket instance to use.