Skip to content

Commit

Permalink
Merge branch '7.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
andrerom committed Sep 30, 2019
2 parents a2ed6a9 + 467086a commit 66582be
Show file tree
Hide file tree
Showing 15 changed files with 388 additions and 376 deletions.
2 changes: 1 addition & 1 deletion eZ/Bundle/EzPublishCoreBundle/Resources/config/cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ parameters:
ezpublish.cache_pool.factory.class: eZ\Bundle\EzPublishCoreBundle\ApiLoader\CacheFactory

services:
ezpublish.cache_pool.inner:
ezpublish.cache_pool:
# As we support custom TagAware services, we set class as interface here so lazy class is "correct"
class: Symfony\Component\Cache\Adapter\TagAwareAdapterInterface
factory: ["@ezpublish.cache_pool.factory", getCachePool]
Expand Down
46 changes: 46 additions & 0 deletions eZ/Publish/API/Repository/Tests/ContentServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4266,6 +4266,52 @@ public function testUpdateContentMetadataInTransactionWithCommit()
$this->assertNotEquals($remoteId, $remoteIdReloaded);
}

/**
* Test for the updateContentMetadata() method, and how cache + transactions play together.
*
* @see \eZ\Publish\API\Repository\ContentService::updateContentMetadata()
* @depends testUpdateContentMetadata
* @depends testLoadContentInfo
*/
public function testUpdateContentMetadataCheckWithinTransaction()
{
$repository = $this->getRepository();
$contentService = $repository->getContentService();
$contentId = $this->generateId('object', 12);

// Load a ContentInfo object, and warmup cache
$contentInfo = $contentService->loadContentInfo($contentId);

// Store remoteId for later testing
$remoteId = $contentInfo->remoteId;

// Start a transaction
$repository->beginTransaction();

try {
// Get metadata update struct and change remoteId
$metadataUpdate = $contentService->newContentMetadataUpdateStruct();
$metadataUpdate->remoteId = md5(microtime(true));

// Update the metadata of the published content object
$contentService->updateContentMetadata(
$contentInfo,
$metadataUpdate
);

// Check that it's been updated
$remoteIdReloaded = $contentService->loadContentInfo($contentId)->remoteId;
$this->assertNotEquals($remoteId, $remoteIdReloaded);

// Commit all changes.
$repository->commit();
} catch (Exception $e) {
// Cleanup hanging transaction on error
$repository->rollback();
throw $e;
}
}

/**
* Test for the deleteVersion() method.
*
Expand Down
12 changes: 4 additions & 8 deletions eZ/Publish/API/Repository/Tests/Regression/EnvTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace eZ\Publish\API\Repository\Tests\Regression;

use eZ\Publish\API\Repository\Tests\BaseTest;
use eZ\Publish\Core\Persistence\Cache\Adapter\TransactionalCacheAdapterDecorator;
use eZ\Publish\Core\Persistence\Cache\Adapter\TransactionalInMemoryCacheAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
Expand All @@ -26,15 +26,11 @@ public function testVerifyCacheDriver()
{
$pool = $this->getSetupFactory()->getServiceContainer()->get('ezpublish.cache_pool');

$this->assertInstanceOf(TransactionalCacheAdapterDecorator::class, $pool);
$this->assertInstanceOf(TransactionalInMemoryCacheAdapter::class, $pool);

$reflectionDecoratedPool = new \ReflectionProperty($pool, 'innerPool');
$reflectionDecoratedPool = new \ReflectionProperty($pool, 'sharedPool');
$reflectionDecoratedPool->setAccessible(true);
$decoratedPool = $reflectionDecoratedPool->getValue($pool);

$reflectionPool = new \ReflectionProperty($decoratedPool, 'pool');
$reflectionPool->setAccessible(true);
$pool = $reflectionPool->getValue($decoratedPool);
$pool = $reflectionDecoratedPool->getValue($pool);

$this->assertInstanceOf(TagAwareAdapter::class, $pool);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
abstract class AbstractInMemoryHandler
{
/**
* NOTE: Instance of this must be InMemoryClearingProxyAdapter in order for cache clearing to affect in-memory cache.
* NOTE: Instance of this must be TransactionalInMemoryCacheAdapter in order for cache clearing to affect in-memory cache.
*
* @var \eZ\Publish\Core\Persistence\Cache\Adapter\TransactionAwareAdapterInterface
*/
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion eZ/Publish/Core/Persistence/Cache/Adapter/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Internal decorator for Symfony Cache TagAwareInterface

Handles making sure the internal in-memory cache is is also cleared when internal and external code is
deleting/invalidating/clearing cache.
deleting/invalidating/clearing cache, and defers invalidation during transactions towards the shared symfony cache pool.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
/**
* Interface for cache adapter which is aware of persistence transactions.
*
* It is used for deferring cache invalidation until transaction is committed.
* It is used for deferring cache invalidation until transaction is committed to avoid race conditions due to
* shared cache pool vs isolated transactions.
*
* @internal
*/
Expand All @@ -22,10 +23,17 @@ interface TransactionAwareAdapterInterface extends TagAwareAdapterInterface
/**
* Called when transaction starts.
*/
public function startTransaction(): void;
public function beginTransaction(): void;

/**
* Called when transaction is either committed or rolled back.
* Called when transaction is committed.
*
* WARNING: Must be called just AFTER database commit, to avoid theoretical cache pool race issues if done before.
*/
public function stopTransaction(): void;
public function commitTransaction(): void;

/**
* Called when transaction is rolled back.
*/
public function rollbackTransaction(): void;
}
Loading

0 comments on commit 66582be

Please sign in to comment.