Skip to content

Commit

Permalink
Apply local cache instead of array cache in various places
Browse files Browse the repository at this point in the history
  • Loading branch information
Rostislav Kreisinger committed Mar 3, 2024
1 parent 00a9e5d commit fca0492
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 145 deletions.
33 changes: 14 additions & 19 deletions packages/framework/src/Model/Product/Brand/BrandCachedFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@

namespace Shopsys\FrameworkBundle\Model\Product\Brand;

use Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade;
use Shopsys\FrameworkBundle\Component\Router\FriendlyUrl\FriendlyUrlFacade;
use Symfony\Contracts\Service\ResetInterface;

class BrandCachedFacade implements ResetInterface
class BrandCachedFacade
{
/**
* @var array<int, array<int, string>>
*/
protected array $brandUrlsIndexedByBrandIdAndDomainId = [];
protected const BRAND_URL_CACHE_NAMESPACE = 'brandUrlCache';

/**
* @param \Shopsys\FrameworkBundle\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade
* @param \Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade $localCacheFacade
*/
public function __construct(protected readonly FriendlyUrlFacade $friendlyUrlFacade)
{
public function __construct(
protected readonly FriendlyUrlFacade $friendlyUrlFacade,
protected readonly LocalCacheFacade $localCacheFacade,
) {
}

/**
Expand All @@ -28,22 +28,17 @@ public function __construct(protected readonly FriendlyUrlFacade $friendlyUrlFac
*/
public function getBrandUrlByDomainId(int $brandId, int $domainId): string
{
if (
!array_key_exists($brandId, $this->brandUrlsIndexedByBrandIdAndDomainId)
|| !array_key_exists($domainId, $this->brandUrlsIndexedByBrandIdAndDomainId[$brandId])
) {
$this->brandUrlsIndexedByBrandIdAndDomainId[$brandId][$domainId] = $this->friendlyUrlFacade->getAbsoluteUrlByRouteNameAndEntityId(
$cacheKey = sprintf('%d~%d', $brandId, $domainId);

if (!$this->localCacheFacade->hasItem(static::BRAND_URL_CACHE_NAMESPACE, $cacheKey)) {
$brandUrl = $this->friendlyUrlFacade->getAbsoluteUrlByRouteNameAndEntityId(
$domainId,
'front_brand_detail',
$brandId,
);
$this->localCacheFacade->save(static::BRAND_URL_CACHE_NAMESPACE, $cacheKey, $brandUrl);
}

return $this->brandUrlsIndexedByBrandIdAndDomainId[$brandId][$domainId];
}

public function reset(): void
{
$this->brandUrlsIndexedByBrandIdAndDomainId = [];
return $this->localCacheFacade->getItem(static::BRAND_URL_CACHE_NAMESPACE, $cacheKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
namespace Shopsys\FrameworkBundle\Model\Product\Collection;

use Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig;
use Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade;
use Shopsys\FrameworkBundle\Model\Product\Collection\Exception\ProductParametersNotLoadedException;
use Shopsys\FrameworkBundle\Model\Product\Product;
use Symfony\Contracts\Service\ResetInterface;

class ProductParametersBatchLoader implements ResetInterface
class ProductParametersBatchLoader
{
/**
* @var string[][]|null[][]
*/
protected array $loadedProductParametersByName = [];
protected const PARAMETERS_CACHE_NAMESPACE = 'parametersByProductIdAndName';

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Collection\ProductCollectionFacade $productCollectionFacade
* @param \Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade $localCacheFacade
*/
public function __construct(protected readonly ProductCollectionFacade $productCollectionFacade)
{
public function __construct(
protected readonly ProductCollectionFacade $productCollectionFacade,
protected readonly LocalCacheFacade $localCacheFacade,
) {
}

/**
Expand All @@ -38,7 +38,7 @@ public function loadForProducts(array $products, DomainConfig $domainConfig): vo
$key = $this->getKey($product, $domainConfig);
$productId = $product->getId();

$this->loadedProductParametersByName[$key] = $parametersByProductIdAndName[$productId] ?? [];
$this->localCacheFacade->save(static::PARAMETERS_CACHE_NAMESPACE, $key, $parametersByProductIdAndName[$productId] ?? []);
}
}

Expand All @@ -51,11 +51,11 @@ public function getProductParametersByName(Product $product, DomainConfig $domai
{
$key = $this->getKey($product, $domainConfig);

if (!array_key_exists($key, $this->loadedProductParametersByName)) {
if (!$this->localCacheFacade->hasItem(static::PARAMETERS_CACHE_NAMESPACE, $key)) {
throw new ProductParametersNotLoadedException($product, $domainConfig);
}

return $this->loadedProductParametersByName[$key];
return $this->localCacheFacade->getItem(static::PARAMETERS_CACHE_NAMESPACE, $key);
}

/**
Expand All @@ -67,9 +67,4 @@ protected function getKey(Product $product, DomainConfig $domainConfig): string
{
return $domainConfig->getId() . '-' . $product->getId();
}

public function reset(): void
{
$this->loadedProductParametersByName = [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,24 @@

use Shopsys\FrameworkBundle\Component\Domain\Config\DomainConfig;
use Shopsys\FrameworkBundle\Component\Image\ImageUrlWithSizeHelper;
use Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade;
use Shopsys\FrameworkBundle\Model\Product\Collection\Exception\ProductImageUrlNotLoadedException;
use Shopsys\FrameworkBundle\Model\Product\Collection\Exception\ProductUrlNotLoadedException;
use Shopsys\FrameworkBundle\Model\Product\Product;
use Symfony\Contracts\Service\ResetInterface;

class ProductUrlsBatchLoader implements ResetInterface
class ProductUrlsBatchLoader
{
/**
* @var string[]
*/
protected array $loadedProductUrls = [];

/**
* @var string[]|null[]
*/
protected array $loadedProductImageUrls = [];
protected const PRODUCT_URLS_CACHE_NAMESPACE = 'loadedProductUrls';
protected const PRODUCT_IMAGE_URLS_CACHE_NAMESPACE = 'loadedProductImageUrls';

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Collection\ProductCollectionFacade $productCollectionFacade
* @param \Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade $localCacheFacade
*/
public function __construct(protected readonly ProductCollectionFacade $productCollectionFacade)
{
public function __construct(
protected readonly ProductCollectionFacade $productCollectionFacade,
protected readonly LocalCacheFacade $localCacheFacade,
) {
}

/**
Expand All @@ -46,8 +42,8 @@ public function loadForProducts(array $products, DomainConfig $domainConfig): vo
$key = $this->getKey($product, $domainConfig);
$productId = $product->getId();

$this->loadedProductUrls[$key] = $productUrlsById[$productId];
$this->loadedProductImageUrls[$key] = $productImageUrlsById[$productId];
$this->localCacheFacade->save(static::PRODUCT_URLS_CACHE_NAMESPACE, $key, $productUrlsById[$productId]);
$this->localCacheFacade->save(static::PRODUCT_IMAGE_URLS_CACHE_NAMESPACE, $key, $productImageUrlsById[$productId]);
}
}

Expand All @@ -60,11 +56,11 @@ public function getProductUrl(Product $product, DomainConfig $domainConfig): str
{
$key = $this->getKey($product, $domainConfig);

if (!array_key_exists($key, $this->loadedProductUrls)) {
if (!$this->localCacheFacade->hasItem(static::PRODUCT_URLS_CACHE_NAMESPACE, $key)) {
throw new ProductUrlNotLoadedException($product, $domainConfig);
}

return $this->loadedProductUrls[$key];
return $this->localCacheFacade->getItem(static::PRODUCT_URLS_CACHE_NAMESPACE, $key);
}

/**
Expand All @@ -76,11 +72,11 @@ public function getProductImageUrl(Product $product, DomainConfig $domainConfig)
{
$key = $this->getKey($product, $domainConfig);

if (!array_key_exists($key, $this->loadedProductImageUrls)) {
if (!$this->localCacheFacade->hasItem(static::PRODUCT_IMAGE_URLS_CACHE_NAMESPACE, $key)) {
throw new ProductImageUrlNotLoadedException($product, $domainConfig);
}

return $this->loadedProductImageUrls[$key];
return $this->localCacheFacade->getItem(static::PRODUCT_IMAGE_URLS_CACHE_NAMESPACE, $key);
}

/**
Expand All @@ -104,10 +100,4 @@ protected function getKey(Product $product, DomainConfig $domainConfig): string
{
return $domainConfig->getId() . '-' . $product->getId();
}

public function reset(): void
{
$this->loadedProductUrls = [];
$this->loadedProductImageUrls = [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,28 @@

namespace Shopsys\FrameworkBundle\Model\Product;

use Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade;
use Shopsys\FrameworkBundle\Model\Localization\Localization;
use Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterRepository;
use Shopsys\FrameworkBundle\Model\Product\Pricing\Exception\MainVariantPriceCalculationException;
use Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser;
use Symfony\Contracts\Service\ResetInterface;

class ProductCachedAttributesFacade implements ResetInterface
class ProductCachedAttributesFacade
{
/**
* @var \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPrice[]
*/
protected array $sellingPricesByProductId;

/**
* @var \Shopsys\FrameworkBundle\Model\Product\Parameter\ProductParameterValue[][]
*/
protected array $parameterValuesByProductId;
protected const SELLING_PRICES_CACHE_NAMESPACE = 'sellingPricesByProductId';
protected const PARAMETER_VALUES_CACHE_NAMESPACE = 'parameterValuesByProductId';

/**
* @param \Shopsys\FrameworkBundle\Model\Product\Pricing\ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser
* @param \Shopsys\FrameworkBundle\Model\Product\Parameter\ParameterRepository $parameterRepository
* @param \Shopsys\FrameworkBundle\Model\Localization\Localization $localization
* @param \Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade $localCacheFacade
*/
public function __construct(
protected readonly ProductPriceCalculationForCustomerUser $productPriceCalculationForCustomerUser,
protected readonly ParameterRepository $parameterRepository,
protected readonly Localization $localization,
protected readonly LocalCacheFacade $localCacheFacade,
) {
}

Expand All @@ -40,16 +35,18 @@ public function __construct(
*/
public function getProductSellingPrice(Product $product)
{
if (isset($this->sellingPricesByProductId[$product->getId()])) {
return $this->sellingPricesByProductId[$product->getId()];
$key = (string)$product->getId();

if ($this->localCacheFacade->hasItem(static::SELLING_PRICES_CACHE_NAMESPACE, $key)) {
return $this->localCacheFacade->getItem(static::SELLING_PRICES_CACHE_NAMESPACE, $key);
}

try {
$productPrice = $this->productPriceCalculationForCustomerUser->calculatePriceForCurrentUser($product);
} catch (MainVariantPriceCalculationException $ex) {
$productPrice = null;
}
$this->sellingPricesByProductId[$product->getId()] = $productPrice;
$this->localCacheFacade->save(static::SELLING_PRICES_CACHE_NAMESPACE, $key, $productPrice);

return $productPrice;
}
Expand All @@ -61,8 +58,10 @@ public function getProductSellingPrice(Product $product)
*/
public function getProductParameterValues(Product $product, ?string $locale = null)
{
if (isset($this->parameterValuesByProductId[$product->getId()])) {
return $this->parameterValuesByProductId[$product->getId()];
$key = (string)$product->getId();

if ($this->localCacheFacade->hasItem(static::PARAMETER_VALUES_CACHE_NAMESPACE, $key)) {
return $this->localCacheFacade->getItem(static::PARAMETER_VALUES_CACHE_NAMESPACE, $key);
}
$locale = $locale ?? $this->localization->getLocale();

Expand All @@ -80,14 +79,8 @@ public function getProductParameterValues(Product $product, ?string $locale = nu
unset($productParameterValues[$index]);
}
}
$this->parameterValuesByProductId[$product->getId()] = $productParameterValues;
$this->localCacheFacade->save(static::PARAMETER_VALUES_CACHE_NAMESPACE, $key, $productParameterValues);

return $productParameterValues;
}

public function reset(): void
{
$this->sellingPricesByProductId = [];
$this->parameterValuesByProductId = [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,26 @@
use Doctrine\ORM\QueryBuilder;
use Elasticsearch\Client;
use Shopsys\FrameworkBundle\Component\Elasticsearch\IndexDefinitionLoader;
use Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade;
use Shopsys\FrameworkBundle\Model\Product\Elasticsearch\ProductIndex;
use Symfony\Contracts\Service\ResetInterface;

class ProductElasticsearchRepository implements ResetInterface
class ProductElasticsearchRepository
{
/**
* @var int[][][]
*/
protected array $foundProductIdsCache = [];
protected const FOUND_PRODUCT_IDS_CACHE_NAMESPACE = 'foundProductIdsCache';

/**
* @param \Elasticsearch\Client $client
* @param \Shopsys\FrameworkBundle\Model\Product\Search\ProductElasticsearchConverter $productElasticsearchConverter
* @param \Shopsys\FrameworkBundle\Model\Product\Search\FilterQueryFactory $filterQueryFactory
* @param \Shopsys\FrameworkBundle\Component\Elasticsearch\IndexDefinitionLoader $indexDefinitionLoader
* @param \Shopsys\FrameworkBundle\Component\LocalCache\LocalCacheFacade $localCacheFacade
*/
public function __construct(
protected readonly Client $client,
protected readonly ProductElasticsearchConverter $productElasticsearchConverter,
protected readonly FilterQueryFactory $filterQueryFactory,
protected readonly IndexDefinitionLoader $indexDefinitionLoader,
protected readonly LocalCacheFacade $localCacheFacade,
) {
}

Expand Down Expand Up @@ -69,14 +68,15 @@ public function addRelevance(QueryBuilder $productQueryBuilder, $searchText)
protected function getFoundProductIds(QueryBuilder $productQueryBuilder, $searchText)
{
$domainId = $productQueryBuilder->getParameter('domainId')->getValue();
$cacheKey = sprintf('%d~%s', $domainId, $searchText);

if (!isset($this->foundProductIdsCache[$domainId][$searchText])) {
if (!$this->localCacheFacade->hasItem(static::FOUND_PRODUCT_IDS_CACHE_NAMESPACE, $cacheKey)) {
$foundProductIds = $this->getProductIdsBySearchText($domainId, $searchText);

$this->foundProductIdsCache[$domainId][$searchText] = $foundProductIds;
$this->localCacheFacade->save(static::FOUND_PRODUCT_IDS_CACHE_NAMESPACE, $cacheKey, $foundProductIds);
}

return $this->foundProductIdsCache[$domainId][$searchText];
return $this->localCacheFacade->getItem(static::FOUND_PRODUCT_IDS_CACHE_NAMESPACE, $cacheKey);
}

/**
Expand Down Expand Up @@ -191,9 +191,4 @@ public function getProductsByFilterQuery(FilterQuery $filterQuery): array

return $this->extractHits($result);
}

public function reset(): void
{
$this->foundProductIdsCache = [];
}
}
Loading

0 comments on commit fca0492

Please sign in to comment.