Skip to content

Commit 6c9c7b8

Browse files
committed
MDVA-27939: Backport inventor patches down to 2.3.2
- Backported https://github.com/magento/inventory/wiki/Known-Performance-Issues (PR magento#2336,magento#2350,magento#2696,magento#2561) & MC-29479
1 parent 26a9fe9 commit 6c9c7b8

File tree

13 files changed

+361
-23
lines changed

13 files changed

+361
-23
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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\Inventory\Model\Source\Command;
9+
10+
use Magento\InventoryApi\Api\GetSourcesAssignedToStockOrderedByPriorityInterface;
11+
12+
/**
13+
* @inheritdoc
14+
*/
15+
class GetSourcesAssignedToStockOrderedByPriorityCache implements GetSourcesAssignedToStockOrderedByPriorityInterface
16+
{
17+
/**
18+
* @var GetSourcesAssignedToStockOrderedByPriority
19+
*/
20+
private $getSourcesAssignedToStock;
21+
22+
/**
23+
* @var array
24+
*/
25+
private $sourcesAssignedToStock = [];
26+
27+
/**
28+
* @param GetSourcesAssignedToStockOrderedByPriority $getSourcesAssignedToStockOrderedByPriority
29+
*/
30+
public function __construct(
31+
GetSourcesAssignedToStockOrderedByPriority $getSourcesAssignedToStockOrderedByPriority
32+
) {
33+
$this->getSourcesAssignedToStock = $getSourcesAssignedToStockOrderedByPriority;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function execute(int $stockId): array
40+
{
41+
if (!isset($this->sourcesAssignedToStock[$stockId])) {
42+
$this->sourcesAssignedToStock[$stockId] = $this->getSourcesAssignedToStock->execute($stockId);
43+
}
44+
45+
return $this->sourcesAssignedToStock[$stockId];
46+
}
47+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<preference for="Magento\InventoryApi\Api\Data\SourceInterface" type="Magento\Inventory\Model\Source"/>
1212
<preference for="Magento\InventoryApi\Api\Data\SourceCarrierLinkInterface" type="Magento\Inventory\Model\SourceCarrierLink"/>
1313
<preference for="Magento\InventoryApi\Api\Data\SourceSearchResultsInterface" type="Magento\Inventory\Model\SourceSearchResults"/>
14-
<preference for="Magento\InventoryApi\Api\GetSourcesAssignedToStockOrderedByPriorityInterface" type="Magento\Inventory\Model\Source\Command\GetSourcesAssignedToStockOrderedByPriority"/>
14+
<preference for="Magento\InventoryApi\Api\GetSourcesAssignedToStockOrderedByPriorityInterface" type="Magento\Inventory\Model\Source\Command\GetSourcesAssignedToStockOrderedByPriorityCache"/>
1515
<preference for="Magento\InventoryApi\Api\GetSourceItemsBySkuInterface" type="Magento\Inventory\Model\SourceItem\Command\GetSourceItemsBySku"/>
1616
<preference for="Magento\InventoryApi\Model\GetSourceCodesBySkusInterface" type="Magento\Inventory\Model\GetSourceCodesBySkus"/>
1717
<preference for="Magento\InventoryApi\Model\SourceCarrierLinkManagementInterface" type="Magento\Inventory\Model\SourceCarrierLinkManagement"/>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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\InventoryCatalog\Model;
9+
10+
use Magento\InventoryCatalogApi\Model\GetProductIdsBySkusInterface;
11+
use Magento\Framework\Serialize\Serializer\Json;
12+
13+
/**
14+
* @inheritdoc
15+
*/
16+
class GetProductIdsBySkusCache implements GetProductIdsBySkusInterface
17+
{
18+
/**
19+
* @var GetProductIdsBySkus
20+
*/
21+
private $getProductIdsBySkus;
22+
23+
/**
24+
* @var Json
25+
*/
26+
private $jsonSerializer;
27+
28+
/**
29+
* @var array
30+
*/
31+
private $productIdsBySkus = [];
32+
33+
/**
34+
* @param GetProductIdsBySkus $getProductIdsBySkus
35+
* @param Json $jsonSerializer
36+
*/
37+
public function __construct(
38+
GetProductIdsBySkus $getProductIdsBySkus,
39+
Json $jsonSerializer
40+
) {
41+
$this->getProductIdsBySkus = $getProductIdsBySkus;
42+
$this->jsonSerializer = $jsonSerializer;
43+
}
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
public function execute(array $skus): array
49+
{
50+
$cacheKey = $this->jsonSerializer->serialize($skus);
51+
if (!isset($this->productIdsBySkus[$cacheKey])) {
52+
$this->productIdsBySkus[$cacheKey] = $this->getProductIdsBySkus->execute($skus);
53+
}
54+
55+
return $this->productIdsBySkus[$cacheKey];
56+
}
57+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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\InventoryCatalog\Model\ResourceModel;
9+
10+
use Magento\InventoryCatalogApi\Model\GetProductTypesBySkusInterface;
11+
use Magento\Framework\Serialize\Serializer\Json;
12+
13+
/**
14+
* @inheritdoc
15+
*/
16+
class GetProductTypesBySkusCache implements GetProductTypesBySkusInterface
17+
{
18+
/**
19+
* @var GetProductTypesBySkus
20+
*/
21+
private $getProductTypesBySkus;
22+
23+
/**
24+
* @var Json
25+
*/
26+
private $jsonSerializer;
27+
28+
/**
29+
* @var array
30+
*/
31+
private $productTypesBySkus = [];
32+
33+
/**
34+
* @param GetProductTypesBySkus $getProductTypesBySkus
35+
* @param Json $jsonSerializer
36+
*/
37+
public function __construct(
38+
GetProductTypesBySkus $getProductTypesBySkus,
39+
Json $jsonSerializer
40+
) {
41+
$this->getProductTypesBySkus = $getProductTypesBySkus;
42+
$this->jsonSerializer = $jsonSerializer;
43+
}
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
public function execute(array $skus): array
49+
{
50+
$cacheKey = $this->jsonSerializer->serialize($skus);
51+
if (!isset($this->productTypesBySkus[$cacheKey])) {
52+
$this->productTypesBySkus[$cacheKey] = $this->getProductTypesBySkus->execute($skus);
53+
}
54+
55+
return $this->productTypesBySkus[$cacheKey];
56+
}
57+
}

app/code/Magento/InventoryCatalog/Plugin/CatalogInventory/Model/Indexer/ModifySelectInProductPriceIndexFilter.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1212
use Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter;
1313
use Magento\Framework\App\ResourceConnection;
14+
use Magento\InventoryApi\Api\Data\StockInterface;
15+
use Magento\InventoryCatalogApi\Api\DefaultStockProviderInterface;
1416
use Magento\InventoryIndexer\Model\StockIndexTableNameResolverInterface;
1517
use Magento\InventorySalesApi\Model\StockByWebsiteIdResolverInterface;
1618

@@ -39,22 +41,30 @@ class ModifySelectInProductPriceIndexFilter
3941
*/
4042
private $stockByWebsiteIdResolver;
4143

44+
/**
45+
* @var DefaultStockProviderInterface
46+
*/
47+
private $defaultStockProvider;
48+
4249
/**
4350
* @param StockIndexTableNameResolverInterface $stockIndexTableNameResolver
4451
* @param StockConfigurationInterface $stockConfiguration
4552
* @param ResourceConnection $resourceConnection
4653
* @param StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver
54+
* @param DefaultStockProviderInterface $defaultStockProvider
4755
*/
4856
public function __construct(
4957
StockIndexTableNameResolverInterface $stockIndexTableNameResolver,
5058
StockConfigurationInterface $stockConfiguration,
5159
ResourceConnection $resourceConnection,
52-
StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver
60+
StockByWebsiteIdResolverInterface $stockByWebsiteIdResolver,
61+
DefaultStockProviderInterface $defaultStockProvider
5362
) {
5463
$this->stockIndexTableNameResolver = $stockIndexTableNameResolver;
5564
$this->stockConfiguration = $stockConfiguration;
5665
$this->resourceConnection = $resourceConnection;
5766
$this->stockByWebsiteIdResolver = $stockByWebsiteIdResolver;
67+
$this->defaultStockProvider = $defaultStockProvider;
5868
}
5969

6070
/**
@@ -84,7 +94,7 @@ public function aroundModifyPrice(
8494
$select->from(['price_index' => $priceTable->getTableName()], []);
8595
$priceEntityField = $priceTable->getEntityField();
8696

87-
if ($this->resourceConnection->getConnection()->isTableExists($stockTable)) {
97+
if (!$this->isDefaultStock($stock) && $this->resourceConnection->getConnection()->isTableExists($stockTable)) {
8898
$select->joinInner(
8999
['product_entity' => $this->resourceConnection->getTableName('catalog_product_entity')],
90100
"product_entity.entity_id = price_index.{$priceEntityField}",

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
99
<preference for="Magento\InventoryCatalogApi\Api\DefaultStockProviderInterface" type="Magento\InventoryCatalog\Model\DefaultStockProvider"/>
1010
<preference for="Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface" type="Magento\InventoryCatalog\Model\DefaultSourceProvider"/>
11-
<preference for="Magento\InventoryCatalogApi\Model\GetProductIdsBySkusInterface" type="Magento\InventoryCatalog\Model\GetProductIdsBySkus"/>
12-
<preference for="Magento\InventoryCatalogApi\Model\GetProductTypesBySkusInterface" type="Magento\InventoryCatalog\Model\ResourceModel\GetProductTypesBySkus" />
11+
<preference for="Magento\InventoryCatalogApi\Model\GetProductIdsBySkusInterface" type="Magento\InventoryCatalog\Model\GetProductIdsBySkusCache"/>
12+
<preference for="Magento\InventoryCatalogApi\Model\GetProductTypesBySkusInterface" type="Magento\InventoryCatalog\Model\ResourceModel\GetProductTypesBySkusCache" />
1313
<preference for="Magento\InventoryCatalogApi\Model\GetSkusByProductIdsInterface" type="Magento\InventoryCatalog\Model\GetSkusByProductIds"/>
1414
<preference for="Magento\InventoryCatalogApi\Model\IsSingleSourceModeInterface" type="Magento\InventoryCatalog\Model\IsSingleSourceMode"/>
1515
<type name="Magento\InventoryApi\Api\StockRepositoryInterface">
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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\InventoryConfiguration\Plugin\InventoryConfiguration\Model;
9+
10+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
11+
use Magento\InventoryConfiguration\Model\GetLegacyStockItem;
12+
13+
/**
14+
* Caching plugin for GetLegacyStockItem service.
15+
*/
16+
class GetLegacyStockItemCache
17+
{
18+
/**
19+
* @var array
20+
*/
21+
private $legacyStockItemsBySku = [];
22+
23+
/**
24+
* Cache the result of service to avoid duplicate queries to the database.
25+
*
26+
* @param GetLegacyStockItem $subject
27+
* @param callable $proceed
28+
* @param string $sku
29+
* @return StockItemInterface
30+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
31+
*/
32+
public function aroundExecute(GetLegacyStockItem $subject, callable $proceed, string $sku): StockItemInterface
33+
{
34+
if (!isset($this->legacyStockItemsBySku[$sku])) {
35+
$this->legacyStockItemsBySku[$sku] = $proceed($sku);
36+
}
37+
38+
return $this->legacyStockItemsBySku[$sku];
39+
}
40+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@
1818
<plugin name="allow_negative_min_qty_in_config"
1919
type="Magento\InventoryConfiguration\Plugin\CatalogInventory\Model\System\Config\Backend\Minqty\AllowNegativeMinQtyInConfigPlugin"/>
2020
</type>
21+
<type name="Magento\InventoryConfiguration\Model\GetLegacyStockItem">
22+
<plugin name="cache_legacy_stock_item"
23+
type="Magento\InventoryConfiguration\Plugin\InventoryConfiguration\Model\GetLegacyStockItemCache"/>
24+
</type>
2125
</config>

app/code/Magento/InventoryIndexer/Model/ResourceModel/GetStockItemData.php

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use Magento\InventoryIndexer\Model\StockIndexTableNameResolverInterface;
1313
use Magento\InventorySalesApi\Model\GetStockItemDataInterface;
1414
use Magento\InventoryIndexer\Indexer\IndexStructure;
15+
use Magento\InventoryCatalogApi\Api\DefaultStockProviderInterface;
16+
use Magento\InventoryCatalogApi\Model\GetProductIdsBySkusInterface;
1517

1618
/**
1719
* @inheritdoc
@@ -28,46 +30,73 @@ class GetStockItemData implements GetStockItemDataInterface
2830
*/
2931
private $stockIndexTableNameResolver;
3032

33+
/**
34+
* @var DefaultStockProviderInterface
35+
*/
36+
private $defaultStockProvider;
37+
38+
/**
39+
* @var GetProductIdsBySkusInterface
40+
*/
41+
private $getProductIdsBySkus;
42+
3143
/**
3244
* @param ResourceConnection $resource
3345
* @param StockIndexTableNameResolverInterface $stockIndexTableNameResolver
46+
* @param DefaultStockProviderInterface $defaultStockProvider
47+
* @param GetProductIdsBySkusInterface $getProductIdsBySkus
3448
*/
3549
public function __construct(
3650
ResourceConnection $resource,
37-
StockIndexTableNameResolverInterface $stockIndexTableNameResolver
51+
StockIndexTableNameResolverInterface $stockIndexTableNameResolver,
52+
DefaultStockProviderInterface $defaultStockProvider,
53+
GetProductIdsBySkusInterface $getProductIdsBySkus
3854
) {
3955
$this->resource = $resource;
4056
$this->stockIndexTableNameResolver = $stockIndexTableNameResolver;
57+
$this->defaultStockProvider = $defaultStockProvider;
58+
$this->getProductIdsBySkus = $getProductIdsBySkus;
4159
}
4260

4361
/**
4462
* @inheritdoc
4563
*/
4664
public function execute(string $sku, int $stockId): ?array
4765
{
48-
$stockItemTableName = $this->stockIndexTableNameResolver->execute($stockId);
49-
5066
$connection = $this->resource->getConnection();
51-
$select = $connection->select()
52-
->from(
67+
$select = $connection->select();
68+
69+
if ($this->defaultStockProvider->getId() === $stockId) {
70+
$productId = current($this->getProductIdsBySkus->execute([$sku]));
71+
$stockItemTableName = $this->resource->getTableName('cataloginventory_stock_status');
72+
$select->from(
73+
$stockItemTableName,
74+
[
75+
GetStockItemDataInterface::QUANTITY => 'qty',
76+
GetStockItemDataInterface::IS_SALABLE => 'stock_status',
77+
]
78+
)->where('product_id = ?', $productId);
79+
80+
return $connection->fetchRow($select) ?: null;
81+
} else {
82+
$stockItemTableName = $this->stockIndexTableNameResolver->execute($stockId);
83+
$select->from(
5384
$stockItemTableName,
5485
[
5586
GetStockItemDataInterface::QUANTITY => IndexStructure::QUANTITY,
5687
GetStockItemDataInterface::IS_SALABLE => IndexStructure::IS_SALABLE,
5788
]
58-
)
59-
->where(IndexStructure::SKU . ' = ?', $sku);
89+
)->where(IndexStructure::SKU . ' = ?', $sku);
6090

61-
try {
62-
if ($connection->isTableExists($stockItemTableName)) {
63-
return $connection->fetchRow($select) ?: null;
64-
}
91+
try {
92+
if ($connection->isTableExists($stockItemTableName)) {
93+
return $connection->fetchRow($select) ?: null;
94+
}
6595

66-
return null;
67-
} catch (\Exception $e) {
68-
throw new LocalizedException(__(
69-
'Could not receive Stock Item data'
70-
), $e);
96+
return null;
97+
} catch (\Exception $e) {
98+
throw new LocalizedException(__('Could not receive Stock Item data'), $e);
99+
}
71100
}
72101
}
73102
}

0 commit comments

Comments
 (0)