Skip to content

Commit f0c6453

Browse files
committed
Avoids indefinite loop of indexers being marked as invalid.
1 parent f39a2e0 commit f0c6453

File tree

2 files changed

+76
-12
lines changed

2 files changed

+76
-12
lines changed

app/code/Magento/Indexer/Model/Processor.php

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
*/
1616
class Processor
1717
{
18+
/**
19+
* @var array
20+
*/
21+
private $sharedIndexesComplete = [];
22+
1823
/**
1924
* @var ConfigInterface
2025
*/
@@ -60,32 +65,83 @@ public function __construct(
6065
*/
6166
public function reindexAllInvalid()
6267
{
63-
$sharedIndexesComplete = [];
6468
foreach (array_keys($this->config->getIndexers()) as $indexerId) {
6569
/** @var Indexer $indexer */
6670
$indexer = $this->indexerFactory->create();
6771
$indexer->load($indexerId);
6872
$indexerConfig = $this->config->getIndexer($indexerId);
73+
$sharedIndex = $indexerConfig['shared_index'];
74+
6975
if ($indexer->isInvalid()) {
7076
// Skip indexers having shared index that was already complete
7177
$sharedIndex = $indexerConfig['shared_index'] ?? null;
72-
if (!in_array($sharedIndex, $sharedIndexesComplete)) {
78+
if (!in_array($sharedIndex, $this->sharedIndexesComplete)) {
7379
$indexer->reindexAll();
74-
} else {
75-
/** @var \Magento\Indexer\Model\Indexer\State $state */
76-
$state = $indexer->getState();
77-
$state->setStatus(StateInterface::STATUS_WORKING);
78-
$state->save();
79-
$state->setStatus(StateInterface::STATUS_VALID);
80-
$state->save();
81-
}
82-
if ($sharedIndex) {
83-
$sharedIndexesComplete[] = $sharedIndex;
80+
81+
if ($sharedIndex) {
82+
$this->validateSharedIndex($sharedIndex);
83+
}
8484
}
8585
}
8686
}
8787
}
8888

89+
/**
90+
* Get indexer ids that have common shared index
91+
*
92+
* @param string $sharedIndex
93+
* @return array
94+
*/
95+
private function getIndexerIdsBySharedIndex(string $sharedIndex): array
96+
{
97+
$indexers = $this->config->getIndexers();
98+
99+
$result = [];
100+
foreach ($indexers as $indexerConfig) {
101+
if ($indexerConfig['shared_index'] == $sharedIndex) {
102+
$result[] = $indexerConfig['indexer_id'];
103+
}
104+
}
105+
106+
return $result;
107+
}
108+
109+
/**
110+
* Validate indexers by shared index ID
111+
*
112+
* @param string $sharedIndex
113+
* @return $this
114+
*/
115+
private function validateSharedIndex(string $sharedIndex): self
116+
{
117+
if (empty($sharedIndex)) {
118+
throw new \InvalidArgumentException(
119+
'The sharedIndex is an invalid shared index identifier. Verify the identifier and try again.'
120+
);
121+
}
122+
123+
$indexerIds = $this->getIndexerIdsBySharedIndex($sharedIndex);
124+
if (empty($indexerIds)) {
125+
return $this;
126+
}
127+
128+
foreach ($indexerIds as $indexerId) {
129+
/** @var \Magento\Indexer\Model\Indexer $indexer */
130+
$indexer = $this->indexerFactory->create();
131+
$indexer->load($indexerId);
132+
/** @var \Magento\Indexer\Model\Indexer\State $state */
133+
$state = $indexer->getState();
134+
$state->setStatus(StateInterface::STATUS_WORKING);
135+
$state->save();
136+
$state->setStatus(StateInterface::STATUS_VALID);
137+
$state->save();
138+
}
139+
140+
$this->sharedIndexesComplete[] = $sharedIndex;
141+
142+
return $this;
143+
}
144+
89145
/**
90146
* Regenerate indexes for all indexers
91147
*

app/code/Magento/Indexer/Test/Unit/Model/ProcessorTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ public function testReindexAllInvalid()
8585

8686
$this->configMock->expects($this->once())->method('getIndexers')->willReturn($indexers);
8787

88+
$this->configMock->expects($this->exactly(2))
89+
->method('getIndexer')
90+
->willReturn(
91+
[
92+
'shared_index' => null
93+
]
94+
);
95+
8896
$state1Mock = $this->createPartialMock(State::class, ['getStatus', '__wakeup']);
8997
$state1Mock->expects(
9098
$this->once()

0 commit comments

Comments
 (0)