Skip to content

Commit 4b66b00

Browse files
committed
MC-32062: [2.4] Deliver first part of Redis improvements
1 parent 6bcc25b commit 4b66b00

File tree

21 files changed

+532
-208
lines changed

21 files changed

+532
-208
lines changed

app/code/Magento/Eav/Model/Config.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,12 @@ class Config
157157

158158
/**
159159
* @param \Magento\Framework\App\CacheInterface $cache
160-
* @param \Magento\Eav\Model\Entity\TypeFactory $entityTypeFactory
161-
* @param \Magento\Eav\Model\ResourceModel\Entity\Type\CollectionFactory $entityTypeCollectionFactory
160+
* @param Entity\TypeFactory $entityTypeFactory
161+
* @param ResourceModel\Entity\Type\CollectionFactory $entityTypeCollectionFactory
162162
* @param \Magento\Framework\App\Cache\StateInterface $cacheState
163163
* @param \Magento\Framework\Validator\UniversalFactory $universalFactory
164-
* @param SerializerInterface $serializer
165-
* @param ScopeConfigInterface $scopeConfig
164+
* @param SerializerInterface|null $serializer
165+
* @param ScopeConfigInterface|null $scopeConfig
166166
* @param array $attributesForPreload
167167
* @codeCoverageIgnore
168168
*/
@@ -374,7 +374,9 @@ protected function _initEntityTypes()
374374
}
375375
\Magento\Framework\Profiler::start('EAV: ' . __METHOD__, ['group' => 'EAV', 'method' => __METHOD__]);
376376

377-
if ($this->isCacheEnabled() && ($cache = $this->_cache->load(self::ENTITIES_CACHE_ID))) {
377+
if ($this->isCacheEnabled() &&
378+
($cache = $this->_cache->load(self::ENTITIES_CACHE_ID))
379+
) {
378380
$this->_entityTypeData = $this->serializer->unserialize($cache);
379381
foreach ($this->_entityTypeData as $typeCode => $data) {
380382
$typeId = $data['entity_type_id'];

app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Set.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
namespace Magento\Eav\Model\ResourceModel\Entity\Attribute;
88

9+
/**
10+
* Basic implementation for attribute sets
11+
*/
912
class Set extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
1013
{
1114
/**
@@ -24,8 +27,6 @@ class Set extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
2427
protected $eavConfig;
2528

2629
/**
27-
* Constructor
28-
*
2930
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
3031
* @param GroupFactory $attrGroupFactory
3132
* @param \Magento\Eav\Model\Config $eavConfig
@@ -54,7 +55,7 @@ protected function _construct()
5455
}
5556

5657
/**
57-
* Perform actions after object save
58+
* Perform actions after object save.
5859
*
5960
* @param \Magento\Framework\Model\AbstractModel $object
6061
* @return $this

app/code/Magento/Eav/etc/di.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,14 @@
209209
</argument>
210210
</arguments>
211211
</type>
212+
<virtualType name="configured_eav_cache" type="Magento\Framework\App\Cache">
213+
<arguments>
214+
<argument name="cacheIdentifier" xsi:type="string">eav</argument>
215+
</arguments>
216+
</virtualType>
217+
<type name="Magento\Eav\Model\Config">
218+
<arguments>
219+
<argument name="cache" xsi:type="object">configured_eav_cache</argument>
220+
</arguments>
221+
</type>
212222
</config>

app/code/Magento/Theme/etc/di.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,24 @@
289289
<argument name="identifierName" xsi:type="string">theme_id</argument>
290290
</arguments>
291291
</type>
292+
<virtualType name="configured_design_cache" type="Magento\Framework\App\Cache">
293+
<arguments>
294+
<argument name="cacheIdentifier" xsi:type="string">layout</argument>
295+
</arguments>
296+
</virtualType>
297+
<virtualType name="design_context" type="Magento\Framework\Model\Context">
298+
<arguments>
299+
<argument name="cacheManager" xsi:type="object">configured_design_cache</argument>
300+
</arguments>
301+
</virtualType>
302+
<type name="Magento\Theme\Model\Design">
303+
<arguments>
304+
<argument name="context" xsi:type="object">design_context</argument>
305+
</arguments>
306+
</type>
307+
<type name="Magento\Theme\Model\Theme\ThemeProvider">
308+
<arguments>
309+
<argument name="cache" xsi:type="object">configured_design_cache</argument>
310+
</arguments>
311+
</type>
292312
</config>

app/etc/di.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,4 +1804,14 @@
18041804
</type>
18051805
<preference for="Magento\Framework\GraphQl\Query\ErrorHandlerInterface" type="Magento\Framework\GraphQl\Query\ErrorHandler"/>
18061806
<preference for="Magento\Framework\Filter\VariableResolverInterface" type="Magento\Framework\Filter\VariableResolver\StrategyResolver"/>
1807+
<virtualType name="configured_block_cache" type="Magento\Framework\App\Cache">
1808+
<arguments>
1809+
<argument name="cacheIdentifier" xsi:type="string">block_html</argument>
1810+
</arguments>
1811+
</virtualType>
1812+
<type name="Magento\Framework\View\Element\Context">
1813+
<arguments>
1814+
<argument name="cache" xsi:type="object">configured_block_cache</argument>
1815+
</arguments>
1816+
</type>
18071817
</config>

dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/FactoryTest.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public function testRemoteSynchronizedCache()
6363
//Removing data
6464
sleep(2);
6565
$this->assertTrue($this->model->remove($secondIdentifier));
66+
$this->assertTrue($this->model->remove($identifier));
6667
$this->assertEquals($this->model->load($identifier), false);
6768
$this->assertEquals($this->model->load($secondIdentifier), false);
6869

@@ -73,11 +74,5 @@ public function testRemoteSynchronizedCache()
7374
//Checking data
7475
$this->assertEquals($this->model->load($identifier), $data);
7576
$this->assertEquals($this->model->load($secondIdentifier), $secondData);
76-
77-
//Removing data
78-
sleep(2);
79-
$this->assertTrue($this->model->remove($identifier));
80-
$this->assertEquals($this->model->load($identifier), false);
81-
$this->assertEquals($this->model->load($secondIdentifier), false);
8277
}
8378
}

lib/internal/Magento/Framework/App/Cache.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
* See COPYING.txt for license details.
55
*/
66

7-
/**
8-
* System cache model
9-
* support id and tags prefix support,
10-
*/
117
namespace Magento\Framework\App;
128

9+
/**
10+
* System cache model support id and tags prefix support.
11+
*/
1312
class Cache implements CacheInterface
1413
{
1514
/**
@@ -30,12 +29,13 @@ class Cache implements CacheInterface
3029
protected $_frontend;
3130

3231
/**
33-
* @param \Magento\Framework\App\Cache\Frontend\Pool $frontendPool
32+
* @param Cache\Frontend\Pool $frontendPool
33+
* @param string|null $cacheIdentifier
3434
*/
35-
public function __construct(\Magento\Framework\App\Cache\Frontend\Pool $frontendPool)
35+
public function __construct(\Magento\Framework\App\Cache\Frontend\Pool $frontendPool, $cacheIdentifier = null)
3636
{
3737
$this->_frontendPool = $frontendPool;
38-
$this->_frontend = $frontendPool->get($this->_frontendIdentifier);
38+
$this->_frontend = $frontendPool->get($cacheIdentifier ?? $this->_frontendIdentifier);
3939
}
4040

4141
/**

lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@ public function get($identifier)
152152
if (isset($this->_instances[$identifier])) {
153153
return $this->_instances[$identifier];
154154
}
155-
throw new \InvalidArgumentException("Cache frontend '{$identifier}' is not recognized.");
155+
156+
if (!isset($this->_instances[self::DEFAULT_FRONTEND_ID])) {
157+
throw new \InvalidArgumentException(
158+
"Cache frontend '{$identifier}' is not recognized. As well as " .
159+
self::DEFAULT_FRONTEND_ID .
160+
"cache is not configured"
161+
);
162+
}
163+
164+
return $this->_instances[self::DEFAULT_FRONTEND_ID];
156165
}
157166
}

lib/internal/Magento/Framework/App/Router/ActionList.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Framework\App\Router;
77

8+
use Magento\Framework\App\Filesystem\DirectoryList;
9+
use Magento\Framework\App\State;
810
use Magento\Framework\Serialize\SerializerInterface;
911
use Magento\Framework\Serialize\Serializer\Serialize;
1012
use Magento\Framework\Module\Dir\Reader as ModuleReader;
@@ -70,12 +72,26 @@ public function __construct(
7072
$this->reservedWords = array_merge($reservedWords, $this->reservedWords);
7173
$this->actionInterface = $actionInterface;
7274
$this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()->get(Serialize::class);
73-
$data = $cache->load($cacheKey);
74-
if (!$data) {
75-
$this->actions = $moduleReader->getActionFiles();
76-
$cache->save($this->serializer->serialize($this->actions), $cacheKey);
75+
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
76+
$state = $objectManager->get(State::class);
77+
78+
if ($state->getMode() === State::MODE_PRODUCTION) {
79+
$directoryList = $objectManager->get(DirectoryList::class);
80+
$file = $directoryList->getPath(DirectoryList::GENERATED_METADATA) . '/' . $cacheKey . '.' . 'php';
81+
82+
if (file_exists($file)) {
83+
$this->actions = (include $file) ?? $moduleReader->getActionFiles();
84+
} else {
85+
$this->actions = $moduleReader->getActionFiles();
86+
}
7787
} else {
78-
$this->actions = $this->serializer->unserialize($data);
88+
$data = $cache->load($cacheKey);
89+
if (!$data) {
90+
$this->actions = $moduleReader->getActionFiles();
91+
$cache->save($this->serializer->serialize($this->actions), $cacheKey);
92+
} else {
93+
$this->actions = $this->serializer->unserialize($data);
94+
}
7995
}
8096
}
8197

lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,8 @@ public function testGet()
208208
}
209209
}
210210

211-
/**
212-
* @expectedException \InvalidArgumentException
213-
* @expectedExceptionMessage Cache frontend 'unknown' is not recognized
214-
*/
215-
public function testGetUnknownFrontendId()
211+
public function testFallbackOnDefault()
216212
{
217-
$this->_model->get('unknown');
213+
$this->assertSame($this->_frontendInstances[Pool::DEFAULT_FRONTEND_ID], $this->_model->get('unknown'));
218214
}
219215
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Framework\Cache\Backend;
8+
9+
/**
10+
* Redis wrapper to extend current implementation behaviour.
11+
*/
12+
class Redis extends \Cm_Cache_Backend_Redis
13+
{
14+
/**
15+
* Local state of preloaded keys.
16+
*
17+
* @var array
18+
*/
19+
private $preloadedData = [];
20+
21+
/**
22+
* Array of keys to be preloaded.
23+
*
24+
* @var array
25+
*/
26+
private $preloadKeys = [];
27+
28+
/**
29+
* @param array $options
30+
*/
31+
public function __construct($options = [])
32+
{
33+
$this->preloadKeys = $options['preload_keys'] ?? [];
34+
parent::__construct($options);
35+
}
36+
37+
/**
38+
* Load value with given id from cache
39+
*
40+
* @param string $id Cache id
41+
* @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
42+
* @return bool|string
43+
*/
44+
public function load($id, $doNotTestCacheValidity = false)
45+
{
46+
if (!empty($this->preloadKeys) && empty($this->preloadedData)) {
47+
$redis = $this->_slave ?? $this->_redis;
48+
$redis = $redis->pipeline();
49+
50+
foreach ($this->preloadKeys as $key) {
51+
$redis->hGet(self::PREFIX_KEY . $key, self::FIELD_DATA);
52+
}
53+
54+
$this->preloadedData = array_filter(array_combine($this->preloadKeys, $redis->exec()));
55+
}
56+
57+
if (isset($this->preloadedData[$id])) {
58+
return $this->_decodeData($this->preloadedData[$id]);
59+
}
60+
61+
return parent::load($id, $doNotTestCacheValidity);
62+
}
63+
64+
/**
65+
* Cover errors on save operations, which may occurs when Redis cannot evict keys, which is expected in some cases.
66+
*
67+
* @param string $data
68+
* @param string $id
69+
* @param array $tags
70+
* @param bool $specificLifetime
71+
* @return bool
72+
*/
73+
public function save($data, $id, $tags = [], $specificLifetime = false)
74+
{
75+
try {
76+
parent::save($data, $id, $tags, $specificLifetime);
77+
} catch (\Throwable $exception) {
78+
return false;
79+
}
80+
81+
return true;
82+
}
83+
}

0 commit comments

Comments
 (0)