Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IBX-819: Shortened persistence cache tags to save memory usage #3114

Merged
merged 23 commits into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 21 additions & 30 deletions doc/specifications/cache/persistence/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,70 +14,61 @@ the cache in a ways so exact items are invalidated on specific bulk operations a
### Tag usage in Persistence Cache

List of tags and their meaning:
- `content-<content-id>` :
- `c-<content-id>` :
_Meta tag used on anything that are affected on changes to content, on content itself as well as location and so on._

- `content-<content-id>-version-<version-number>`
- `c-<content-id>-v-<version-number>`
_Used for specific versions, usuefull for clearing cache of a specific draft on changes for instance._

- `content-fields-<content-id>` :
_Used on content/user object itself (with fields), for use when operations affects field values but not content meta info._
- `cft-<content-type-id>` :
_Used on content/user object itself (with fields), for use when operations affect content type or its content fields._

- `content-fields-type-<content-type-id>` :
_Same as above, but specifically for use when content type changes affecting content fields of it's type._

- `location-<location-id>` :
- `l-<location-id>` :
_Meta tag used on anything that are affected on changes to location, needs to be invalidated if location changes._

- `location-path-<location-id>` :
- `lp-<location-id>` :
_Same as above, additional tags for all parents, for operations that changes the tree itself, like move/remove/(..)._

- `location-data-<location-id>` :
_Used on location, and invalidated when operations affect the properties on location only, e.g. update._

- `location-path-data-<location-id>` :
_Same as above, but for operations affecting data in the tree, e.g. hide/unhide._

- `language-<language-id>` :
- `la-<language-id>` :
_Used on languages, and invalidated when operations affect a language._

- `type-<type-id>` :
- `t-<type-id>` :
_Used on types, and invalidated when operations affect a type._

- `type-group-<type-group-id>` :
- `tg-<type-group-id>` :
_Used on type groups, and invalidated when operations affect a type groups._

- `type-map` :
- `tm` :
_Used on type map info, like calculated info on searchable fields, invalidated on type changes._

- `state-<type-id>` :
- `s-<type-id>` :
_Used on states, and invalidated when operations affect a state._

- `state-group-<state-group-id>` :
- `sg-<state-group-id>` :
_Used on state groups, and invalidated when operations affect a state groups._

- `section-<section-id>` :
- `se-<section-id>` :
_Used on sections, and invalidated when operations affect a section._

- `urlAlias-location-<location-id>` :
- `urlal-<location-id>` :
_Used on url alias, invalidated on location operations affecting url alias._

- `urlAlias-notFound` :
- `urlanf` :
_Used for not found lookups for url alias by url as this is hot spot, invalidated on urlAlias creation._

- `role-<role-id>` :
- `r-<role-id>` :
_Used on roles, and invalidated when operations affect a role (role and policy operations)._

- `policy-<policy-id>` :
- `p-<policy-id>` :
_Used on policies, and invalidated when operations affect a policy._

- `role-assignment-<role-assignment-id>` :
- `ra-<role-assignment-id>` :
_Used on role assignment, and invalidated when operations affect a role assignment._

- `role-assignment-group-list-<content-id>` :
- `ragl-<content-id>` :
_Used for list of role assignment, and invalidated when operations affect it from content side._

- `role-assignment-role-list-<content-id>` :
- `rarl-<content-id>` :
_Used for list of role assignment, and invalidated when operations affect it from role side._


Expand All @@ -87,7 +78,7 @@ List of tags and their meaning:
On `LocationHandler->create()` the following invalidation is done:

```php
$this->cache->invalidateTags(['content-' . $locationStruct->contentId, 'role-assignment-group-list-' . $locationStruct->contentId]);
$this->cache->invalidateTags(['c-' . $locationStruct->contentId, 'ragl-' . $locationStruct->contentId]);
```

This is done since the operation might affect content if main location changes, and as it might affect roles assignments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware;
use eZ\Publish\SPI\Variation\VariationHandler;
use Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface;
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
use Symfony\Component\Routing\RequestContext;

Expand All @@ -19,6 +20,14 @@
*/
class AliasGeneratorDecorator implements VariationHandler, SiteAccessAware
{
private const IMAGE_VARIATION_TAG = 'image_variation';
private const IMAGE_VARIATION_SITEACCESS_TAG = 'image_variation_siteaccess';
private const IMAGE_VARIATION_CONTENT_TAG = 'image_variation_content';
private const IMAGE_VARIATION_FIELD_TAG = 'image_variation_field';
private const IMAGE_VARIATION_NAME_TAG = 'image_variation_name';
private const CONTENT_TAG = 'content';
private const CONTENT_VERSION_TAG = 'content_version';

/** @var \eZ\Publish\SPI\Variation\VariationHandler */
private $aliasGenerator;

Expand All @@ -31,16 +40,25 @@ class AliasGeneratorDecorator implements VariationHandler, SiteAccessAware
/** @var \Symfony\Component\Routing\RequestContext */
private $requestContext;

/** @var \Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface */
private $cacheIdentifierGenerator;

/**
* @param \eZ\Publish\SPI\Variation\VariationHandler $aliasGenerator
* @param \Symfony\Component\Cache\Adapter\TagAwareAdapterInterface $cache
* @param \Symfony\Component\Routing\RequestContext $requestContext
* @param \Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface $cacheIdentifierGenerator
*/
public function __construct(VariationHandler $aliasGenerator, TagAwareAdapterInterface $cache, RequestContext $requestContext)
{
public function __construct(
VariationHandler $aliasGenerator,
TagAwareAdapterInterface $cache,
RequestContext $requestContext,
CacheIdentifierGeneratorInterface $cacheIdentifierGenerator
) {
$this->aliasGenerator = $aliasGenerator;
$this->cache = $cache;
$this->requestContext = $requestContext;
$this->cacheIdentifierGenerator = $cacheIdentifierGenerator;
}

/**
Expand Down Expand Up @@ -85,8 +103,8 @@ public function setSiteAccess(SiteAccess $siteAccess = null)
private function getCacheKey(Field $field, VersionInfo $versionInfo, $variationName)
{
return sprintf(
'ez-image-variation-%s-%s-%s-%d-%d-%d-%s-%s',
$this->siteAccess ? $this->siteAccess->name : 'default',
$this->cacheIdentifierGenerator->generateKey(self::IMAGE_VARIATION_TAG, [], true) . '-%s-%s-%s-%d-%d-%d-%s-%s',
$this->siteAccess->name ?? 'default',
$this->requestContext->getScheme(),
$this->requestContext->getHost(),
$this->requestContext->getScheme() === 'https' ? $this->requestContext->getHttpsPort() : $this->requestContext->getHttpPort(),
Expand All @@ -102,13 +120,14 @@ private function getTagsForVariation(Field $field, VersionInfo $versionInfo, str
$contentId = $versionInfo->getContentInfo()->id;

return [
'image-variation',
'image-variation-name-' . $variationName,
'image-variation-siteaccess-' . ($this->siteAccess ? $this->siteAccess->name : 'default'),
'image-variation-content-' . $contentId,
'image-variation-field-' . $field->id,
'content-' . $contentId,
'content-' . $contentId . '-version-' . $versionInfo->versionNo,
$this->cacheIdentifierGenerator->generateTag(self::IMAGE_VARIATION_TAG),
$this->cacheIdentifierGenerator->generateTag(self::IMAGE_VARIATION_NAME_TAG, [$variationName]),
$this->cacheIdentifierGenerator->generateTag(self::IMAGE_VARIATION_SITEACCESS_TAG, [$this->siteAccess->name ?? 'default']),
$this->cacheIdentifierGenerator->generateTag(self::IMAGE_VARIATION_CONTENT_TAG, [$contentId]),
$this->cacheIdentifierGenerator->generateTag(self::IMAGE_VARIATION_FIELD_TAG, [$field->id]),
$this->cacheIdentifierGenerator->generateTag(self::CONTENT_TAG, [$contentId]),
$this->cacheIdentifierGenerator->generateTag(self::CONTENT_TAG, [$contentId]),
$this->cacheIdentifierGenerator->generateTag(self::CONTENT_VERSION_TAG, [$contentId, $versionInfo->versionNo]),
];
}
}
1 change: 1 addition & 0 deletions eZ/Bundle/EzPublishCoreBundle/Resources/config/image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ services:
- '@ezpublish.image_alias.imagine.variation.imagine_alias_generator'
- '@ezpublish.cache_pool'
- '@router.request_context'
- '@Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface'
calls:
- [setSiteAccess, ['@ezpublish.siteaccess']]

Expand Down
9 changes: 8 additions & 1 deletion eZ/Publish/Core/Persistence/Cache/AbstractHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
namespace eZ\Publish\Core\Persistence\Cache;

use Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface;
use eZ\Publish\SPI\Persistence\Handler as PersistenceHandler;
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;

Expand All @@ -25,21 +26,27 @@ abstract class AbstractHandler
/** @var \eZ\Publish\Core\Persistence\Cache\PersistenceLogger */
protected $logger;

/** @var \Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface */
protected $cacheIdentifierGenerator;

/**
* Setups current handler with everything needed.
*
* @param \Symfony\Component\Cache\Adapter\TagAwareAdapterInterface $cache
* @param \eZ\Publish\SPI\Persistence\Handler $persistenceHandler
* @param \eZ\Publish\Core\Persistence\Cache\PersistenceLogger $logger
* @param \Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface $cacheIdentifierGenerator
*/
public function __construct(
TagAwareAdapterInterface $cache,
PersistenceHandler $persistenceHandler,
PersistenceLogger $logger
PersistenceLogger $logger,
CacheIdentifierGeneratorInterface $cacheIdentifierGenerator
) {
$this->cache = $cache;
$this->persistenceHandler = $persistenceHandler;
$this->logger = $logger;
$this->cacheIdentifierGenerator = $cacheIdentifierGenerator;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use eZ\Publish\Core\Persistence\Cache\Adapter\TransactionAwareAdapterInterface;
use eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache;
use eZ\Publish\SPI\Persistence\Handler as PersistenceHandler;
use Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface;

/**
* Internal abstract handler for use in other SPI Persistence Cache Handlers.
Expand All @@ -20,22 +21,29 @@ abstract class AbstractInMemoryPersistenceHandler extends AbstractInMemoryHandle
/** @var \eZ\Publish\SPI\Persistence\Handler */
protected $persistenceHandler;

/** @var \Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface */
protected $cacheIdentifierGenerator;

/**
* Setups current handler with everything needed.
*
* @param \eZ\Publish\Core\Persistence\Cache\Adapter\TransactionAwareAdapterInterface $cache
* @param \eZ\Publish\Core\Persistence\Cache\PersistenceLogger $logger
* @param \eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache $inMemory
* @param \eZ\Publish\SPI\Persistence\Handler $persistenceHandler
* @param \Ibexa\Core\Persistence\Cache\Tag\CacheIdentifierGeneratorInterface $cacheIdentifierGenerator
*/
public function __construct(
TransactionAwareAdapterInterface $cache,
PersistenceLogger $logger,
InMemoryCache $inMemory,
PersistenceHandler $persistenceHandler
PersistenceHandler $persistenceHandler,
CacheIdentifierGeneratorInterface $cacheIdentifierGenerator
) {
parent::__construct($cache, $logger, $inMemory);

$this->persistenceHandler = $persistenceHandler;
$this->cacheIdentifierGenerator = $cacheIdentifierGenerator;

$this->init();
}
Expand Down
19 changes: 13 additions & 6 deletions eZ/Publish/Core/Persistence/Cache/BookmarkHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
*/
class BookmarkHandler extends AbstractHandler implements BookmarkHandlerInterface
{
private const BOOKMARK_IDENTIFIER = 'bookmark';
private const LOCATION_IDENTIFIER = 'location';
private const USER_IDENTIFIER = 'user';
private const LOCATION_PATH_IDENTIFIER = 'location_path';

/**
* {@inheritdoc}
*/
Expand All @@ -40,7 +45,9 @@ public function delete(int $bookmarkId): void

$this->persistenceHandler->bookmarkHandler()->delete($bookmarkId);

$this->cache->invalidateTags(['bookmark-' . $bookmarkId]);
$this->cache->invalidateTags([
$this->cacheIdentifierGenerator->generateTag(self::BOOKMARK_IDENTIFIER, [$bookmarkId]),
]);
}

/**
Expand All @@ -50,7 +57,7 @@ public function loadByUserIdAndLocationId(int $userId, array $locationIds): arra
{
return $this->getMultipleCacheItems(
$locationIds,
'ez-bookmark-' . $userId . '-',
$this->cacheIdentifierGenerator->generateKey(self::BOOKMARK_IDENTIFIER, [$userId], true) . '-',
konradoboza marked this conversation as resolved.
Show resolved Hide resolved
function (array $missingIds) use ($userId) {
$this->logger->logCall(__CLASS__ . '::loadByUserIdAndLocationId', [
'userId' => $userId,
Expand All @@ -61,14 +68,14 @@ function (array $missingIds) use ($userId) {
},
function (Bookmark $bookmark) {
$tags = [
'bookmark-' . $bookmark->id,
'location-' . $bookmark->locationId,
'user-' . $bookmark->userId,
$this->cacheIdentifierGenerator->generateTag(self::BOOKMARK_IDENTIFIER, [$bookmark->id]),
$this->cacheIdentifierGenerator->generateTag(self::LOCATION_IDENTIFIER, [$bookmark->locationId]),
$this->cacheIdentifierGenerator->generateTag(self::USER_IDENTIFIER, [$bookmark->userId]),
];

$location = $this->persistenceHandler->locationHandler()->load($bookmark->locationId);
foreach (explode('/', trim($location->pathString, '/')) as $locationId) {
$tags[] = 'location-path-' . $locationId;
$tags[] = $this->cacheIdentifierGenerator->generateTag(self::LOCATION_PATH_IDENTIFIER, [$locationId]);
}

return $tags;
Expand Down
Loading