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

[framework] Two level cache #3031

Open
wants to merge 3 commits into
base: 14.0
Choose a base branch
from
Open

Conversation

RostislavKreisinger
Copy link
Contributor

@RostislavKreisinger RostislavKreisinger commented Feb 18, 2024

Q A
Description, reason for the PR After implementing several projects, I was missing some formal tool for working with local cache in the platform. I wanted the programmer to be able to safely use the local cache and to ensure that this cache is automatically cleared during special events within the application's life cycle, or when the entity manager is cleaned. Here is my proposed implementation providing a number of support functions for working with cached data.
New feature Yes
BC breaks No
Fixes issues ...
Have you read and signed our License Agreement for contributions? Yes

🌐 Live Preview:

@RostislavKreisinger RostislavKreisinger changed the title Two level cache [framework] Two level cache Mar 30, 2024
Copy link
Contributor

@vitek-rostislav vitek-rostislav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, nice job, I have added a few notes and suggestions, check them out, please. Also, could you please rebase on the 15.0 branch and add upgrade notes? 🙏


use Exception;

class LocalCacheException extends Exception
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any usage for this LocalCacheException? I would say both NamespaceCacheKeyNotFoundException and ValueCacheKeyNotFoundException can extend the common Exception directly, or?

*/
public function __construct(string $namespace, string $valueKey)
{
parent::__construct(sprintf('Value with keys "%s" and "%s" not found', $namespace, $valueKey));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be more precise here

Suggested change
parent::__construct(sprintf('Value with keys "%s" and "%s" not found', $namespace, $valueKey));
parent::__construct(sprintf('Value with namespace "%s" and key "%s" not found', $namespace, $valueKey));


class LocalCacheFacade implements ResetInterface
{
protected const NOT_ALLOWED_CHARS = '{}()/\@:".';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
protected const NOT_ALLOWED_CHARS = '{}()/\@:".';
protected const string NOT_ALLOWED_CHARS = '{}()/\@:".';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, why these characters? I found a constant that could be maybe used here but it is missing the last two characters.

Symfony\Contracts\Cache\ItemInterface::RESERVED_CHARACTERS

use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Contracts\Service\ResetInterface;

class LocalCacheFacade implements ResetInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not mind explicitly implementing the ResetInterface, however, it seems like Symfony takes care of it itself - ArrayAdapter implements ResettableInterface (that extends ResetInterface) so I feel like it would work by default, what do you think?

/**
* @param string $key
*/
protected function fixKey(string &$key): void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go with a more descriptive name here, what about replaceNotAllowedCharactersInKey or something like that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I am struggling a bit with the reference here, I know it is a standard technique, we just do not use that often so it always triggers my attention. Personally, I would not use it that way and I would simply create a function with a return value. But this is just my personal approach, I do not insist on rewriting the current state 😉

$categoryId,
$key = (string)$categoryId;

if (!$this->localCacheFacade->hasItem(static::HEUREKA_CATEGORY_FULL_NAMES_CACHE_NAMESPACE, $key)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getOrSaveValue() can be used here, right?

* @var array<string, array<int, array<string, array<string|null, int>>>>
*/
private array $positionByEntityAndType = [];
private const POSITION_BY_ENTITY_AND_TYPE_CACHE_NAMESPACE = 'positionByEntityAndType';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private const POSITION_BY_ENTITY_AND_TYPE_CACHE_NAMESPACE = 'positionByEntityAndType';
private const string POSITION_BY_ENTITY_AND_TYPE_CACHE_NAMESPACE = 'positionByEntityAndType';

@@ -79,11 +78,15 @@ private function getPositionForNewEntity(EntityFileUploadInterface $entity): int
$entityId = $entity->getEntityId();
$type = $entity->getType();
$uploadEntityType = $this->getUploadEntityType($entity);
$key = sprintf('%s~%s~%s~%s', $entityName, $entityId, $type, $uploadEntityType);

if ($this->localCacheFacade->hasItem(self::POSITION_BY_ENTITY_AND_TYPE_CACHE_NAMESPACE, $key)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about getOrSave()? 😇

* @var string[][][]
*/
private array $readySeoCategorySetup;
private const READY_SEO_CATEGORY_SETUP_CACHE_NAMESPACE = 'readySeoCategorySetup';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private const READY_SEO_CATEGORY_SETUP_CACHE_NAMESPACE = 'readySeoCategorySetup';
private const string READY_SEO_CATEGORY_SETUP_CACHE_NAMESPACE = 'readySeoCategorySetup';

if (($this->readySeoCategorySetup[$domainId][$categoryId] ?? null) === null) {
$key = sprintf('%d~%d', $categoryId, $domainId);

if (!$this->localCacheFacade->hasItem(self::READY_SEO_CATEGORY_SETUP_CACHE_NAMESPACE, $key)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer getOrSave()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants