class RiakCache in Plug 7
Riak cache provider.
@link www.doctrine-project.org @since 1.1 @author Guilherme Blanco <guilhermeblanco@hotmail.com>
Hierarchy
- class \Doctrine\Common\Cache\CacheProvider implements Cache, ClearableCache, FlushableCache, MultiGetCache
- class \Doctrine\Common\Cache\RiakCache
Expanded class hierarchy of RiakCache
1 file declares its use of RiakCache
- RiakCacheTest.php in lib/
doctrine/ cache/ tests/ Doctrine/ Tests/ Common/ Cache/ RiakCacheTest.php
File
- lib/
doctrine/ cache/ lib/ Doctrine/ Common/ Cache/ RiakCache.php, line 35
Namespace
Doctrine\Common\CacheView 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
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Cache:: |
constant | |||
Cache:: |
constant | |||
Cache:: |
constant | Only for backward compatibility (may be removed in next major release) | ||
Cache:: |
constant | |||
Cache:: |
constant | |||
Cache:: |
constant | |||
CacheProvider:: |
private | property | The namespace to prefix all cache ids with. | |
CacheProvider:: |
private | property | The namespace version. | |
CacheProvider:: |
public | function |
Tests if an entry exists in the cache. Overrides Cache:: |
|
CacheProvider:: |
public | function |
Deletes a cache entry. Overrides Cache:: |
|
CacheProvider:: |
public | function |
Deletes all cache entries. Overrides ClearableCache:: |
|
CacheProvider:: |
constant | |||
CacheProvider:: |
protected | function | Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it. | 4 |
CacheProvider:: |
public | function |
Fetches an entry from the cache. Overrides Cache:: |
|
CacheProvider:: |
public | function |
Returns an associative array of values for keys is found in cache. Overrides MultiGetCache:: |
|
CacheProvider:: |
public | function |
Flushes all cache entries. Overrides FlushableCache:: |
|
CacheProvider:: |
public | function | Retrieves the namespace that prefixes all cache ids. | |
CacheProvider:: |
private | function | Returns the namespace cache key. | |
CacheProvider:: |
private | function | Prefixes the passed id with the configured namespace value. | |
CacheProvider:: |
private | function | Returns the namespace version. | |
CacheProvider:: |
public | function |
Retrieves cached information from the data store. Overrides Cache:: |
|
CacheProvider:: |
public | function |
Puts data into the cache. Overrides Cache:: |
|
CacheProvider:: |
public | function | Sets the namespace to prefix all cache ids with. | 1 |
RiakCache:: |
private | property | ||
RiakCache:: |
protected | function |
Tests if an entry exists in the cache. Overrides CacheProvider:: |
|
RiakCache:: |
protected | function |
Deletes a cache entry. Overrides CacheProvider:: |
|
RiakCache:: |
protected | function |
Fetches an entry from the cache. Overrides CacheProvider:: |
|
RiakCache:: |
protected | function |
Flushes all cache entries. Overrides CacheProvider:: |
|
RiakCache:: |
protected | function |
Retrieves cached information from the data store. Overrides CacheProvider:: |
|
RiakCache:: |
protected | function |
Puts data into the cache. Overrides CacheProvider:: |
|
RiakCache:: |
constant | |||
RiakCache:: |
private | function | Check if a given Riak Object have expired. | |
RiakCache:: |
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:: |
public | function | Sets the riak bucket instance to use. |