Skip to content

Commit

Permalink
Refactoring region access strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
fabios committed Oct 1, 2013
1 parent 4dbbdbf commit 2e23555
Show file tree
Hide file tree
Showing 29 changed files with 487 additions and 214 deletions.
48 changes: 13 additions & 35 deletions docs/en/reference/second-level-cache.rst
Expand Up @@ -208,25 +208,28 @@ Built-in Strategies

Caching Strategies are responsible for access cache regions.

* ``Doctrine\ORM\Cache\Access\ReadOnlyRegionAccess`` implements ``READ_ONLY``
* ``Doctrine\ORM\Cache\Access\NonStrictReadWriteRegionAccessStrategy`` implements ``NONSTRICT_READ_WRITE``
* ``Doctrine\ORM\Cache\Access\ConcurrentRegionAccessStrategy`` implements ``READ_WRITE`` requires a ``ConcurrentRegion``

``Doctrine\ORM\Cache\RegionAccess`` and ``Doctrine\ORM\Cache\ConcurrentRegionAccess``
* ``Doctrine\ORM\Cache\Access\ReadOnlyEntityRegionAccessStrategy`` implements ``READ_ONLY`` for entities
* ``Doctrine\ORM\Cache\Access\ReadOnlyCollectionRegionAccessStrategy`` implements ``READ_ONLY`` for collections
* ``Doctrine\ORM\Cache\Access\NonStrictReadWriteEntityRegionAccessStrategy`` implements ``NONSTRICT_READ_WRITE`` for entities
* ``Doctrine\ORM\Cache\Access\NonStrictReadWriteCollectionRegionAccessStrategy`` implements ``NONSTRICT_READ_WRITE`` for collections
* ``Doctrine\ORM\Cache\Access\ReadWriteEntityRegionAccessStrategy`` implements ``READ_WRITE`` requires a ``ConcurrentRegion`` for entities
* ``Doctrine\ORM\Cache\Access\ReadWriteCollectionRegionAccessStrategy`` implements ``READ_WRITE`` requires a ``ConcurrentRegion`` for collections

``Doctrine\ORM\Cache\RegionAccessStrategy``, ``Doctrine\ORM\Cache\CollectionRegionAccessStrategy`` and ``Doctrine\ORM\Cache\ConcurrentRegionAccessStrategy``
Defines contracts that should be implemented by caching strategies.

If you want to support locking for ``READ_WRITE`` strategies you should implement ``ConcurrentRegionAccess``; ``RegionAccess`` otherwise.
If you want to support locking for ``READ_WRITE`` strategies you should implement ``ConcurrentRegionAccessStrategy``; ``RegionAccessStrategy`` otherwise.


``Doctrine\ORM\Cache\RegionAccess``
``Doctrine\ORM\Cache\RegionAccessStrategy``

Interface for all region access strategies.

.. code-block:: php
<?php
interface RegionAccess
interface RegionAccessStrategy
{
/**
* Get the wrapped data cache region
Expand Down Expand Up @@ -258,31 +261,6 @@ Interface for all region access strategies.
*/
public function put(CacheKey $key, CacheEntry $entry);
/**
* Called after an item has been inserted (after the transaction completes).
*
* @param \Doctrine\ORM\Cache\CacheKey $key The cache key.
* @param \Doctrine\ORM\Cache\CacheEntry $entry The cache entry.
*
* @return boolean TRUE If the contents of the cache actual were changed.
*
* @throws \Doctrine\ORM\Cache\CacheException
*/
public function afterInsert(CacheKey $key, CacheEntry $entry);
/**
* Called after an item has been updated (after the transaction completes).
*
* @param \Doctrine\ORM\Cache\CacheKey $key The cache key.
* @param \Doctrine\ORM\Cache\CacheEntry $entry The cache entry.
* @param \Doctrine\ORM\Cache\Lock $lock The lock obtained from lockItem
*
* @return boolean TRUE If the contents of the cache actual were changed.
*
* @throws \Doctrine\ORM\Cache\CacheException
*/
public function afterUpdate(CacheKey $key, CacheEntry $entry, Lock $lock = null);
/**
* Forcibly evict an item from the cache immediately without regard for locks.
*
Expand Down Expand Up @@ -384,7 +362,7 @@ It allows you to provide a specific implementation of the following components :
* Build an entity RegionAccess for the input entity.
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata.
* @return \Doctrine\ORM\Cache\RegionAccess The built region access.
* @return \Doctrine\ORM\Cache\EntityRegionAccessStrategy The built region access.
*/
public function buildEntityRegionAccessStrategy(ClassMetadata $metadata);
Expand All @@ -393,7 +371,7 @@ It allows you to provide a specific implementation of the following components :
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata.
* @param string $fieldName The association field name.
* @return \Doctrine\ORM\Cache\RegionAccess The built region access.
* @return \Doctrine\ORM\Cache\CollectionRegionAccessStrategy The built region access.
*/
public function buildCollectionRegionAccessStrategy(ClassMetadata $metadata, $fieldName);
Expand Down
Expand Up @@ -20,24 +20,23 @@

namespace Doctrine\ORM\Cache\Access;

use Doctrine\ORM\Cache\RegionAccess;
use Doctrine\ORM\Cache\RegionAccessStrategy;
use Doctrine\ORM\Cache\CacheEntry;
use Doctrine\ORM\Cache\CacheKey;
use Doctrine\ORM\Cache\Region;
use Doctrine\ORM\Cache\Lock;

/**
* Specific non-strict read/write region access strategy
* Abstract region access strategy
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class NonStrictReadWriteRegionAccessStrategy implements RegionAccess
abstract class AbstractRegionAccessStrategy implements RegionAccessStrategy
{
/**
* @var \Doctrine\ORM\Cache\Region
*/
private $region;
protected $region;

/**
* @param \Doctrine\ORM\Cache\Region $region
Expand All @@ -55,22 +54,6 @@ public function getRegion()
return $this->region;
}

/**
* {@inheritdoc}
*/
public function afterInsert(CacheKey $key, CacheEntry $entry)
{
return $this->region->put($key, $entry);
}

/**
* {@inheritdoc}
*/
public function afterUpdate(CacheKey $key, CacheEntry $entry, Lock $lock = null)
{
return $this->region->put($key, $entry);
}

/**
* {@inheritdoc}
*/
Expand Down
@@ -0,0 +1,34 @@
<?php

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ORM\Cache\Access;

use Doctrine\ORM\Cache\CollectionRegionAccessStrategy;

/**
* Specific non-strict read/write region access strategy
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class NonStrictReadWriteCollectionRegionAccessStrategy extends AbstractRegionAccessStrategy implements CollectionRegionAccessStrategy
{

}
@@ -0,0 +1,51 @@
<?php

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ORM\Cache\Access;

use Doctrine\ORM\Cache\EntityRegionAccessStrategy;
use Doctrine\ORM\Cache\CacheEntry;
use Doctrine\ORM\Cache\CacheKey;
use Doctrine\ORM\Cache\Lock;

/**
* Specific non-strict read/write region access strategy
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class NonStrictReadWriteEntityRegionAccessStrategy extends AbstractRegionAccessStrategy implements EntityRegionAccessStrategy
{
/**
* {@inheritdoc}
*/
public function afterInsert(CacheKey $key, CacheEntry $entry)
{
return $this->region->put($key, $entry);
}

/**
* {@inheritdoc}
*/
public function afterUpdate(CacheKey $key, CacheEntry $entry, Lock $lock = null)
{
return $this->region->put($key, $entry);
}
}
@@ -0,0 +1,34 @@
<?php

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ORM\Cache\Access;

use Doctrine\ORM\Cache\CollectionRegionAccessStrategy;

/**
* Specific read-only region access strategy
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class ReadOnlyCollectionRegionAccessStrategy extends AbstractRegionAccessStrategy implements CollectionRegionAccessStrategy
{

}
Expand Up @@ -31,7 +31,7 @@
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class ReadOnlyRegionAccess extends NonStrictReadWriteRegionAccessStrategy
class ReadOnlyEntityRegionAccessStrategy extends NonStrictReadWriteEntityRegionAccessStrategy
{
/**
* {@inheritdoc}
Expand Down
@@ -0,0 +1,102 @@
<?php

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ORM\Cache\Access;

use Doctrine\ORM\Cache\ConcurrentRegionAccessStrategy;
use Doctrine\ORM\Cache\CollectionRegionAccessStrategy;
use Doctrine\ORM\Cache\ConcurrentRegion;
use Doctrine\ORM\Cache\CacheException;
use Doctrine\ORM\Cache\LockException;
use Doctrine\ORM\Cache\CacheEntry;
use Doctrine\ORM\Cache\CacheKey;
use Doctrine\ORM\Cache\Lock;

/**
* Region access strategies for concurrently managed data.
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class ReadWriteCollectionRegionAccessStrategy extends AbstractRegionAccessStrategy implements ConcurrentRegionAccessStrategy, CollectionRegionAccessStrategy
{
/**
* @param \Doctrine\ORM\Cache\ConcurrentRegion $region
*/
public function __construct(ConcurrentRegion $region)
{
$this->region = $region;
}

/**
* {@inheritdoc}
*/
public function put(CacheKey $key, CacheEntry $entry)
{
$writeLock = null;

try {
if ( ! ($writeLock = $this->region->writeLock($key))) {
return false;
}

if ( ! $this->region->put($key, $entry, $writeLock)) {
return false;
}

$this->region->writeUnlock($key, $writeLock);

return true;

} catch (LockException $exc) {

if ($writeLock) {
$this->region->writeUnlock($key, $writeLock);
}

throw new $exc;
} catch (\Exception $exc) {

if ($writeLock) {
$this->region->writeUnlock($key, $writeLock);
}

throw new CacheException($exc->getMessage(), $exc->getCode(), $exc);
}

return false;
}

/**
* {@inheritdoc}
*/
public function lockItem(CacheKey $key)
{
return $this->region->readLock($key);
}

/**
* {@inheritdoc}
*/
public function unlockItem(CacheKey $key, Lock $lock)
{
return $this->region->readUnlock($key, $lock);
}
}

0 comments on commit 2e23555

Please sign in to comment.