Skip to content

Commit 6868558

Browse files
Merge pull request #710 from magento-dragons/pr-22-develop
Fixed issues: - MAGETWO-58174: When catalog is being indexed it should index in place or leverage an index alias so store can still function during a long index run - MAGETWO-61829: SOAP/REST tests fail on develop branch but builds are green - MAGETWO-62387: Travis Build Fail - 2.2.0 - MAGETWO-59990: Disable child product doesn't work in Configurable variations grid - MAGETWO-58701: memory_limit issue after running customer_grid indexer - MAGETWO-61159: Configurable Product visible on the Category when options are Out of Stock and Disabled
2 parents 6ae3418 + 7976cb1 commit 6868558

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1361
-143
lines changed

Diff for: app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php

+47-9
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,68 @@
66
namespace Magento\CatalogSearch\Model\Indexer;
77

88
use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\FullFactory;
9+
use Magento\CatalogSearch\Model\Indexer\Scope\State;
910
use Magento\CatalogSearch\Model\ResourceModel\Fulltext as FulltextResource;
10-
use \Magento\Framework\Search\Request\Config as SearchRequestConfig;
11+
use Magento\Framework\App\ObjectManager;
12+
use Magento\Framework\Search\Request\Config as SearchRequestConfig;
1113
use Magento\Framework\Search\Request\DimensionFactory;
1214
use Magento\Store\Model\StoreManagerInterface;
1315

16+
/**
17+
* Provide functionality for Fulltext Search indexing
18+
*/
1419
class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
1520
{
1621
/**
1722
* Indexer ID in configuration
1823
*/
1924
const INDEXER_ID = 'catalogsearch_fulltext';
2025

21-
/** @var array index structure */
26+
/**
27+
* @var array index structure
28+
*/
2229
protected $data;
2330

2431
/**
2532
* @var IndexerHandlerFactory
2633
*/
2734
private $indexerHandlerFactory;
35+
2836
/**
2937
* @var StoreManagerInterface
3038
*/
3139
private $storeManager;
40+
3241
/**
33-
* @var DimensionFactory
42+
* @var \Magento\Framework\Search\Request\DimensionFactory
3443
*/
3544
private $dimensionFactory;
45+
3646
/**
37-
* @var Full
47+
* @var \Magento\CatalogSearch\Model\Indexer\Fulltext\Action\Full
3848
*/
3949
private $fullAction;
50+
4051
/**
4152
* @var FulltextResource
4253
*/
4354
private $fulltextResource;
55+
4456
/**
45-
* @var SearchRequestConfig
57+
* @var \Magento\Framework\Search\Request\Config
4658
*/
4759
private $searchRequestConfig;
4860

61+
/**
62+
* @var IndexSwitcherInterface
63+
*/
64+
private $indexSwitcher;
65+
66+
/**
67+
* @var \Magento\CatalogSearch\Model\Indexer\Scope\State
68+
*/
69+
private $indexScopeState;
70+
4971
/**
5072
* @param FullFactory $fullActionFactory
5173
* @param IndexerHandlerFactory $indexerHandlerFactory
@@ -54,6 +76,8 @@ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\F
5476
* @param FulltextResource $fulltextResource
5577
* @param SearchRequestConfig $searchRequestConfig
5678
* @param array $data
79+
* @param IndexSwitcherInterface $indexSwitcher
80+
* @param Scope\State $indexScopeState
5781
*/
5882
public function __construct(
5983
FullFactory $fullActionFactory,
@@ -62,7 +86,9 @@ public function __construct(
6286
DimensionFactory $dimensionFactory,
6387
FulltextResource $fulltextResource,
6488
SearchRequestConfig $searchRequestConfig,
65-
array $data
89+
array $data,
90+
IndexSwitcherInterface $indexSwitcher = null,
91+
State $indexScopeState = null
6692
) {
6793
$this->fullAction = $fullActionFactory->create(['data' => $data]);
6894
$this->indexerHandlerFactory = $indexerHandlerFactory;
@@ -71,6 +97,14 @@ public function __construct(
7197
$this->fulltextResource = $fulltextResource;
7298
$this->searchRequestConfig = $searchRequestConfig;
7399
$this->data = $data;
100+
if (null === $indexSwitcher) {
101+
$indexSwitcher = ObjectManager::getInstance()->get(IndexSwitcherInterface::class);
102+
}
103+
if (null === $indexScopeState) {
104+
$indexScopeState = ObjectManager::getInstance()->get(State::class);
105+
}
106+
$this->indexSwitcher = $indexSwitcher;
107+
$this->indexScopeState = $indexScopeState;
74108
}
75109

76110
/**
@@ -106,10 +140,14 @@ public function executeFull()
106140
'data' => $this->data
107141
]);
108142
foreach ($storeIds as $storeId) {
109-
$dimension = $this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId]);
110-
$saveHandler->cleanIndex([$dimension]);
111-
$saveHandler->saveIndex([$dimension], $this->fullAction->rebuildStoreIndex($storeId));
143+
$dimensions = [$this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId])];
144+
$this->indexScopeState->useTemporaryIndex();
145+
146+
$saveHandler->cleanIndex($dimensions);
147+
$saveHandler->saveIndex($dimensions, $this->fullAction->rebuildStoreIndex($storeId));
112148

149+
$this->indexSwitcher->switchIndex($dimensions);
150+
$this->indexScopeState->useRegularIndex();
113151
}
114152
$this->fulltextResource->resetSearchResults();
115153
$this->searchRequestConfig->reset();

Diff for: app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,27 @@
1212
use Magento\Framework\Search\Request\Dimension;
1313
use Magento\Framework\Indexer\IndexStructureInterface;
1414
use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
15+
use Magento\Framework\Search\Request\IndexScopeResolverInterface;
1516

1617
class IndexStructure implements IndexStructureInterface
1718
{
1819
/**
1920
* @var Resource
2021
*/
2122
private $resource;
23+
2224
/**
2325
* @var IndexScopeResolver
2426
*/
2527
private $indexScopeResolver;
2628

2729
/**
2830
* @param ResourceConnection $resource
29-
* @param IndexScopeResolver $indexScopeResolver
31+
* @param IndexScopeResolverInterface $indexScopeResolver
3032
*/
3133
public function __construct(
3234
ResourceConnection $resource,
33-
IndexScopeResolver $indexScopeResolver
35+
IndexScopeResolverInterface $indexScopeResolver
3436
) {
3537
$this->resource = $resource;
3638
$this->indexScopeResolver = $indexScopeResolver;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CatalogSearch\Model\Indexer;
7+
8+
/**
9+
* Provides a functionality to replace main index with its temporary representation
10+
*/
11+
interface IndexSwitcherInterface
12+
{
13+
/**
14+
* Switch current index with temporary index
15+
*
16+
* It will drop current index table and rename temporary index table to the current index table.
17+
*
18+
* @param array $dimensions
19+
* @return void
20+
*/
21+
public function switchIndex(array $dimensions);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\CatalogSearch\Model\Indexer;
8+
9+
use Magento\Framework\App\Config\ScopeConfigInterface;
10+
use Magento\Framework\ObjectManagerInterface;
11+
use Magento\Store\Model\ScopeInterface;
12+
13+
/**
14+
* Proxy for adapter-specific index switcher
15+
*/
16+
class IndexSwitcherProxy implements IndexSwitcherInterface
17+
{
18+
/**
19+
* Object Manager instance
20+
*
21+
* @var ObjectManagerInterface
22+
*/
23+
private $objectManager = null;
24+
25+
/**
26+
* Instance name to create
27+
*
28+
* @var string
29+
*/
30+
private $handlers;
31+
32+
/**
33+
* @var ScopeConfigInterface
34+
*/
35+
private $scopeConfig;
36+
37+
/**
38+
* Configuration path by which current indexer handler stored
39+
*
40+
* @var string
41+
*/
42+
private $configPath;
43+
44+
/**
45+
* Factory constructor
46+
*
47+
* @param ObjectManagerInterface $objectManager
48+
* @param ScopeConfigInterface $scopeConfig
49+
* @param string $configPath
50+
* @param string[] $handlers
51+
*/
52+
public function __construct(
53+
ObjectManagerInterface $objectManager,
54+
ScopeConfigInterface $scopeConfig,
55+
$configPath,
56+
array $handlers = []
57+
) {
58+
$this->objectManager = $objectManager;
59+
$this->scopeConfig = $scopeConfig;
60+
$this->configPath = $configPath;
61+
$this->handlers = $handlers;
62+
}
63+
64+
/**
65+
* {@inheritDoc}
66+
*
67+
* As index switcher is an optional part of the search SPI, it may be not defined by a search engine.
68+
* It is especially reasonable for search engines with pre-defined indexes declaration (like old SOLR and Sphinx)
69+
* which cannot create temporary indexes on the fly.
70+
* That's the reason why this method do nothing for the case
71+
* when switcher is not defined for a specific search engine.
72+
*/
73+
public function switchIndex(array $dimensions)
74+
{
75+
$currentHandler = $this->scopeConfig->getValue($this->configPath, ScopeInterface::SCOPE_STORE);
76+
if (!isset($this->handlers[$currentHandler])) {
77+
return;
78+
}
79+
$this->create($currentHandler)->switchIndex($dimensions);
80+
}
81+
82+
/**
83+
* Create indexer handler
84+
*
85+
* @param string $handler
86+
* @return IndexSwitcherInterface
87+
*/
88+
private function create($handler)
89+
{
90+
$indexSwitcher = $this->objectManager->create($this->handlers[$handler]);
91+
92+
if (!$indexSwitcher instanceof IndexSwitcherInterface) {
93+
throw new \InvalidArgumentException(
94+
$handler . ' index switcher doesn\'t implement ' . IndexSwitcherInterface::class
95+
);
96+
}
97+
98+
return $indexSwitcher;
99+
}
100+
}

Diff for: app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77

88
use Magento\Eav\Model\Config;
99
use Magento\Framework\App\ResourceConnection;
10-
use Magento\Framework\DB\Adapter\AdapterInterface;
1110
use Magento\Framework\Indexer\SaveHandler\IndexerInterface;
1211
use Magento\Framework\Indexer\IndexStructureInterface;
1312
use Magento\Framework\Search\Request\Dimension;
1413
use Magento\Framework\Search\Request\IndexScopeResolverInterface;
1514
use Magento\Framework\Indexer\SaveHandler\Batch;
16-
use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
1715

1816
class IndexerHandler implements IndexerInterface
1917
{
@@ -62,7 +60,7 @@ class IndexerHandler implements IndexerInterface
6260
* @param ResourceConnection $resource
6361
* @param Config $eavConfig
6462
* @param Batch $batch
65-
* @param \Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver $indexScopeResolver
63+
* @param IndexScopeResolverInterface $indexScopeResolver
6664
* @param array $data
6765
* @param int $batchSize
6866
*/
@@ -71,7 +69,7 @@ public function __construct(
7169
ResourceConnection $resource,
7270
Config $eavConfig,
7371
Batch $batch,
74-
IndexScopeResolver $indexScopeResolver,
72+
IndexScopeResolverInterface $indexScopeResolver,
7573
array $data,
7674
$batchSize = 100
7775
) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CatalogSearch\Model\Indexer\Scope;
7+
8+
use Magento\CatalogSearch\Model\Indexer\IndexSwitcherInterface;
9+
use Magento\Framework\App\ResourceConnection;
10+
use Magento\Framework\Search\Request\IndexScopeResolverInterface;
11+
12+
/**
13+
* Provides a functionality to replace main index with its temporary representation
14+
*/
15+
class IndexSwitcher implements IndexSwitcherInterface
16+
{
17+
/**
18+
* @var Resource
19+
*/
20+
private $resource;
21+
22+
/**
23+
* @var ScopeProxy
24+
*/
25+
private $resolver;
26+
27+
/**
28+
* @var State
29+
*/
30+
private $state;
31+
32+
/**
33+
* @param ResourceConnection $resource
34+
* @param IndexScopeResolverInterface $indexScopeResolver
35+
* @param State $state
36+
*/
37+
public function __construct(
38+
ResourceConnection $resource,
39+
IndexScopeResolverInterface $indexScopeResolver,
40+
State $state
41+
) {
42+
$this->resource = $resource;
43+
$this->resolver = $indexScopeResolver;
44+
$this->state = $state;
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
* @throws IndexTableNotExistException
50+
*/
51+
public function switchIndex(array $dimensions)
52+
{
53+
if (State::USE_TEMPORARY_INDEX === $this->state->getState()) {
54+
$index = \Magento\CatalogSearch\Model\Indexer\Fulltext::INDEXER_ID;
55+
56+
$temporalIndexTable = $this->resolver->resolve($index, $dimensions);
57+
if (!$this->resource->getConnection()->isTableExists($temporalIndexTable)) {
58+
throw new IndexTableNotExistException(
59+
__(
60+
"Temporary table for index $index doesn't exist,"
61+
. " which is inconsistent with state of scope resolver"
62+
)
63+
);
64+
}
65+
66+
$this->state->useRegularIndex();
67+
$tableName = $this->resolver->resolve($index, $dimensions);
68+
if ($this->resource->getConnection()->isTableExists($tableName)) {
69+
$this->resource->getConnection()->dropTable($tableName);
70+
}
71+
72+
$this->resource->getConnection()->renameTable($temporalIndexTable, $tableName);
73+
$this->state->useTemporaryIndex();
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)