Skip to content

Commit a796656

Browse files
authored
LYNX-176: Fix unrelated caches invalidation (#123)
* LYNX-151: Cache identity for attributeForms query * LYNX-151: Tests [in progress] * LYNX-151: Cache identity for attributeForms query - tests * LYNX-151: Cache identity for attributeForms query - pre CR changes * LYNX-151: Cache identity for attributeForms query - pre CR changes * LYNX-151: Cache identity for attributeForms query - pre CR changes * LYNX-151: Cache identity for attributeForms query - pre CR changes * LYNX-151: Cache identity for attributeForms query - pre CR changes * LYNX-151: Add cache invalidation test * LYNX-151: Add cache invalidation test * LYNX-151: Add tests for cahce invalidation for shared attribute (two forms) * LYNX-151: Add cache invalidation test - refactoring (cont.) * LYNX-151: Test for multiple stores * LYNX-151: Refactoring * LYNX-151: Work in progress * LYNX-151: Add cache tag for AttributesForm query * LYNX-151: Cache identity for attributeForms query - bugfixes, refactoring * LYNX-151: CR changes * LYNX-151: CR changes * LYNX-151: CR changes * LYNX-151: Refactoring, bugfixing * LYNX-151: Refactoring, bugfixing; adding more specific cache tagging for attributesForm * LYNX-151: Refactoring; bugfixing; test coverage improvements * LNX-151: Fix static tests; cleanup the code * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-151: Refactoring; bugfixing; revert unnecessary changes * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-151: pre-CR changes * LYNX-151: Bugfixing * LYNX-176: Move invalidation of attributesList caches to InvalidateAttributeRelatedCaches plugin * LYNX-171: Some refactoring; remove cache tag creation for attributesList from AttributePlugin * LYNX-151: Fix for Static tests; refactoring * LYNX-151: Refactoring * LYNX-151: Refactoring * LYNX-176: Refactoring; added Cache Id headers to AttributesListCache tests * LYNX-176: Refactoring; remove unnecessary tag(s) invalidation from InvalidateAttributeRelatedCaches * LYNX-176: Refactoring; added tests to cover additional scenarios * LYNX-176: Refacting; fix issue with tag for entity types * LYNX-176: Refactoring * LYNX-176: Refactoring * LYNX-176: Tests fixes; refactoring * LYNX-176: CR changes; refactoring * LYNX-176: delete temp file * LYNX-176: Formatting
1 parent 41883fa commit a796656

File tree

11 files changed

+1053
-64
lines changed

11 files changed

+1053
-64
lines changed

app/code/Magento/Customer/Model/Metadata/AttributeMetadataCache.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public function clean()
156156
$this->cache->clean(
157157
[
158158
Type::CACHE_TAG,
159-
Attribute::CACHE_TAG,
159+
Attribute::CACHE_TAG
160160
]
161161
);
162162
}

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

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

7-
/**
8-
* EAV attribute resource model (Using Forms)
9-
*
10-
* @method \Magento\Eav\Model\Attribute\Data\AbstractData|null getDataModel()
11-
* Get data model linked to attribute or null.
12-
*
13-
* @author Magento Core Team <[email protected]>
14-
*/
158
namespace Magento\Eav\Model;
169

1710
use Magento\Store\Model\Website;
@@ -23,14 +16,7 @@
2316
class Attribute extends \Magento\Eav\Model\Entity\Attribute
2417
{
2518
/**
26-
* Name of the module
27-
* Override it
28-
*/
29-
//const MODULE_NAME = 'Magento_Eav';
30-
31-
/**
32-
* Name of the module
33-
* Override it
19+
* @var string
3420
*/
3521
protected $_eventObject = 'attribute';
3622

@@ -80,7 +66,7 @@ public function afterSave()
8066
}
8167

8268
/**
83-
* Return forms in which the attribute
69+
* Return forms in which the attribute is being used
8470
*
8571
* @return array
8672
*/
@@ -110,6 +96,18 @@ public function getValidateRules()
11096
return [];
11197
}
11298

99+
/**
100+
* @inheritdoc
101+
*/
102+
public function setData($key, $value = null): Attribute
103+
{
104+
if ($key === 'used_in_forms') {
105+
$this->setOrigData('used_in_forms', $this->getData('used_in_forms') ?? []);
106+
}
107+
parent::setData($key, $value);
108+
return $this;
109+
}
110+
113111
/**
114112
* Set validate rules
115113
*
@@ -188,7 +186,7 @@ public function getMultilineCount()
188186
}
189187

190188
/**
191-
* {@inheritdoc}
189+
* @inheritdoc
192190
*/
193191
public function afterDelete()
194192
{
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Eav\Model\Cache;
9+
10+
use Magento\Framework\Api\AttributeInterface;
11+
use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
12+
use Magento\Eav\Model\Entity\Attribute;
13+
14+
/**
15+
* Cache identity provider for attributes form query
16+
*/
17+
class AttributesFormIdentity implements IdentityInterface
18+
{
19+
public const CACHE_TAG = 'EAV_FORM';
20+
/**
21+
* @inheritDoc
22+
*/
23+
public function getIdentities(array $resolvedData): array
24+
{
25+
if (empty($resolvedData['items'])) {
26+
return [];
27+
}
28+
29+
$identities = [];
30+
31+
if ($resolvedData['formCode'] !== '') {
32+
$identities[] = sprintf(
33+
"%s_%s_FORM",
34+
self::CACHE_TAG,
35+
$resolvedData['formCode'] ?? ''
36+
);
37+
}
38+
39+
foreach ($resolvedData['items'] as $item) {
40+
if ($item['attribute'] instanceof AttributeInterface) {
41+
$identities[] = sprintf(
42+
"%s_%s",
43+
Attribute::CACHE_TAG,
44+
$item['attribute']->getAttributeId()
45+
);
46+
}
47+
}
48+
return $identities;
49+
}
50+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public function clear()
218218
$this->_cache->clean(
219219
[
220220
\Magento\Eav\Model\Cache\Type::CACHE_TAG,
221-
\Magento\Eav\Model\Entity\Attribute::CACHE_TAG,
221+
\Magento\Eav\Model\Entity\Attribute::CACHE_TAG
222222
]
223223
);
224224
return $this;

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use Magento\Framework\Exception\LocalizedException;
1313
use Magento\Framework\Stdlib\DateTime;
1414
use Magento\Framework\Stdlib\DateTime\DateTimeFormatterInterface;
15+
use Magento\Eav\Model\Config;
16+
use Magento\Eav\Model\Cache\AttributesFormIdentity;
1517

1618
/**
1719
* EAV Entity attribute model
@@ -522,7 +524,35 @@ public function getSortWeight($setId)
522524
*/
523525
public function getIdentities()
524526
{
525-
return [self::CACHE_TAG . '_' . $this->getId()];
527+
$identities = [self::CACHE_TAG . '_' . $this->getId()];
528+
529+
if (($this->hasDataChanges() || $this->isDeleted())) {
530+
$identities[] = sprintf(
531+
"%s_%s_ENTITY",
532+
Config::ENTITIES_CACHE_ID,
533+
strtoupper($this->getEntityType()->getEntityTypeCode())
534+
);
535+
536+
$formsUsedBeforeChange = $this->getOrigData('used_in_forms') ?? [];
537+
$usedInForms = $this->getUsedInForms() ?? [];
538+
539+
if ($formsUsedBeforeChange != $usedInForms) {
540+
$formsToInvalidate = array_merge(
541+
array_diff($formsUsedBeforeChange, $usedInForms),
542+
array_diff($usedInForms, $formsUsedBeforeChange)
543+
);
544+
545+
foreach ($formsToInvalidate as $form) {
546+
$identities[] = sprintf(
547+
"%s_%s_FORM",
548+
AttributesFormIdentity::CACHE_TAG,
549+
$form
550+
);
551+
};
552+
}
553+
}
554+
555+
return $identities;
526556
}
527557

528558
/**

app/code/Magento/EavGraphQl/Model/Resolver/AttributesForm.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,34 @@ public function resolve(
5151
array $value = null,
5252
array $args = null
5353
) {
54+
5455
if (empty($args['formCode'])) {
5556
throw new GraphQlInputException(__('Required parameter "%1" of type string.', 'formCode'));
5657
}
5758

58-
$attributes = $this->getAttributesFormComposite->execute($args['formCode']);
59-
if ($this->isAnAdminForm($args['formCode']) || $attributes === null) {
59+
$formCode = $args['formCode'];
60+
61+
$attributes = $this->getAttributesFormComposite->execute($formCode);
62+
if ($this->isAnAdminForm($formCode) || $attributes === null) {
6063
return [
6164
'items' => [],
6265
'errors' => [
6366
[
6467
'type' => 'ENTITY_NOT_FOUND',
65-
'message' => (string) __('Form "%form" could not be found.', ['form' => $args['formCode']])
68+
'message' => (string) __('Form "%form" could not be found.', ['form' => $formCode])
6669
]
6770
]
6871
];
6972
}
7073

71-
return $this->getAttributesMetadata->execute(
72-
$attributes,
73-
(int)$context->getExtensionAttributes()->getStore()->getId()
74+
return array_merge(
75+
[
76+
'formCode' => $formCode
77+
],
78+
$this->getAttributesMetadata->execute(
79+
$attributes,
80+
(int)$context->getExtensionAttributes()->getStore()->getId()
81+
)
7482
);
7583
}
7684

app/code/Magento/EavGraphQl/Model/Resolver/Cache/AttributesListIdentity.php

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,40 @@
88
namespace Magento\EavGraphQl\Model\Resolver\Cache;
99

1010
use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
11+
use Magento\Framework\Api\AttributeInterface;
12+
use Magento\Eav\Model\Config;
13+
use Magento\Eav\Model\Entity\Attribute;
1114

1215
/**
1316
* Cache identity provider for attributes list query results.
1417
*/
1518
class AttributesListIdentity implements IdentityInterface
1619
{
17-
public const CACHE_TAG = 'ATTRIBUTES_LIST';
18-
1920
/**
2021
* @inheritDoc
2122
*/
2223
public function getIdentities(array $resolvedData): array
2324
{
24-
if (empty($resolvedData['items'])) {
25+
if (empty($resolvedData['items']) || !is_array($resolvedData['items'][0])) {
2526
return [];
2627
}
2728

28-
if (!is_array($resolvedData['items'][0])) {
29-
return [];
29+
$item = $resolvedData['items'][0];
30+
$identities = [];
31+
32+
if ($item['entity_type'] !== '') {
33+
$identities[] = Config::ENTITIES_CACHE_ID . "_" . $item['entity_type'] . "_ENTITY";
3034
}
3135

32-
return [sprintf(
33-
"%s_%s",
34-
self::CACHE_TAG,
35-
$resolvedData['items'][0]['entity_type']
36-
)];
36+
foreach ($resolvedData['items'] as $item) {
37+
if ($item['attribute'] instanceof AttributeInterface) {
38+
$identities[] = sprintf(
39+
"%s_%s",
40+
Attribute::CACHE_TAG,
41+
$item['attribute']->getAttributeId()
42+
);
43+
}
44+
}
45+
return $identities;
3746
}
3847
}

app/code/Magento/EavGraphQl/Plugin/Eav/AttributePlugin.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
namespace Magento\EavGraphQl\Plugin\Eav;
99

1010
use Magento\Eav\Model\Entity\Attribute;
11-
use Magento\EavGraphQl\Model\Resolver\Cache\AttributesListIdentity;
1211
use Magento\Framework\Api\AttributeInterface;
1312

1413
/**
@@ -36,8 +35,7 @@ public function afterGetIdentities(Attribute $subject, array $result): array
3635
$subject->getOrigData(AttributeInterface::ATTRIBUTE_CODE)
3736
?? $subject->getData(AttributeInterface::ATTRIBUTE_CODE)
3837
)
39-
],
40-
[AttributesListIdentity::CACHE_TAG.'_'.strtoupper($subject->getEntityType()->getEntityTypeCode())]
38+
]
4139
);
4240
}
4341
}

app/code/Magento/EavGraphQl/etc/schema.graphqls

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ type Query {
99
@cache(cacheIdentity: "Magento\\EavGraphQl\\Model\\Resolver\\Cache\\CustomAttributeMetadataIdentity")
1010
@deprecated(reason: "Use `customAttributeMetadataV2` query instead.")
1111
customAttributeMetadataV2(attributes: [AttributeInput!]): AttributesMetadataOutput! @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesMetadata") @doc(description: "Retrieve EAV attributes metadata.") @cache(cacheIdentity: "Magento\\EavGraphQl\\Model\\Resolver\\Cache\\CustomAttributeMetadataV2Identity")
12-
attributesForm(formCode: String! @doc(description: "Form code.")): AttributesFormOutput! @resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesForm") @doc(description: "Retrieve EAV attributes associated to a frontend form.")
12+
attributesForm(formCode: String! @doc(description: "Form code.")): AttributesFormOutput!
13+
@resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesForm")
14+
@doc(description: "Retrieve EAV attributes associated to a frontend form.")
15+
@cache(cacheIdentity: "Magento\\Eav\\Model\\Cache\\AttributesFormIdentity")
1316
attributesList(entityType: AttributeEntityTypeEnum! @doc(description: "Entity type.")):
1417
AttributesMetadataOutput
1518
@resolver(class: "Magento\\EavGraphQl\\Model\\Resolver\\AttributesList")

0 commit comments

Comments
 (0)