Skip to content

Commit e45a944

Browse files
author
Viktor Kopin
committed
MC-39718: Process Manager always exits successfully if the amount of functions(i.e. indexer dimensions) is lower than the MAGE_INDEXER_THREADS_COUNT env variable
1 parent 38d712e commit e45a944

File tree

2 files changed

+187
-1
lines changed

2 files changed

+187
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,12 @@ private function multiThreadsExecute($userFunctions)
111111
$this->startChildProcess($userFunction);
112112
}
113113
}
114-
// phpcs:ignore Magento2.CodeAnalysis.EmptyBlock,Magento2.Functions.DiscouragedFunction
114+
// phpcs:ignore Magento2.Functions.DiscouragedFunction
115115
while (pcntl_waitpid(0, $status) != -1) {
116116
//Waiting for the completion of child processes
117+
if ($status > 0) {
118+
$this->failInChildProcess = true;
119+
}
117120
}
118121

119122
if ($this->failInChildProcess) {
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
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\Indexer\Test\Unit\Model;
9+
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Indexer\Model\ProcessManager;
12+
use PHPUnit\Framework\TestCase;
13+
14+
/**
15+
* Class covers process manager execution test logic
16+
*/
17+
class ProcessManagerTest extends TestCase
18+
{
19+
/**
20+
* @dataProvider functionsWithErrorProvider
21+
* @param array $userFunctions
22+
* @param int $threadsCount
23+
* @return void
24+
*/
25+
public function testFailureInChildProcessHandleMultiThread(array $userFunctions, int $threadsCount): void
26+
{
27+
$connectionMock = $this->createMock(ResourceConnection::class);
28+
$processManager = new ProcessManager(
29+
$connectionMock,
30+
null,
31+
$threadsCount
32+
);
33+
34+
try {
35+
$processManager->execute($userFunctions);
36+
$this->fail('Exception was not handled');
37+
} catch (\RuntimeException $exception) {
38+
$this->assertEquals('Fail in child process', $exception->getMessage());
39+
}
40+
}
41+
42+
/**
43+
* Closure functions data provider for multi thread execution
44+
*
45+
* @return array
46+
* @SuppressWarnings(PHPMD.ExitExpression)
47+
*/
48+
public function functionsWithErrorProvider(): array
49+
{
50+
return [
51+
'more_threads_than_functions' => [
52+
'user_functions' => [
53+
// @codingStandardsIgnoreStart
54+
function () {
55+
exit(1);
56+
},
57+
function () {
58+
exit(0);
59+
},
60+
function () {
61+
exit(0);
62+
},
63+
// @codingStandardsIgnoreEnd
64+
],
65+
'threads_count' => 4,
66+
],
67+
'less_threads_than_functions' => [
68+
'user_functions' => [
69+
// @codingStandardsIgnoreStart
70+
function () {
71+
exit(1);
72+
},
73+
function () {
74+
exit(0);
75+
},
76+
function () {
77+
exit(0);
78+
},
79+
// @codingStandardsIgnoreEnd
80+
],
81+
'threads_count' => 2,
82+
],
83+
'equal_threads_and_functions' => [
84+
'user_functions' => [
85+
// @codingStandardsIgnoreStart
86+
function () {
87+
exit(1);
88+
},
89+
function () {
90+
exit(0);
91+
},
92+
function () {
93+
exit(0);
94+
},
95+
// @codingStandardsIgnoreEnd
96+
],
97+
'threads_count' => 3,
98+
],
99+
];
100+
}
101+
102+
/**
103+
* @dataProvider successFunctionsProvider
104+
* @param array $userFunctions
105+
* @param int $threadsCount
106+
* @return void
107+
*/
108+
public function testSuccessChildProcessHandleMultiThread(array $userFunctions, int $threadsCount): void
109+
{
110+
$connectionMock = $this->createMock(ResourceConnection::class);
111+
$processManager = new ProcessManager(
112+
$connectionMock,
113+
null,
114+
$threadsCount
115+
);
116+
117+
try {
118+
$processManager->execute($userFunctions);
119+
} catch (\RuntimeException $exception) {
120+
$this->fail('Exception was not handled');
121+
}
122+
}
123+
124+
/**
125+
* Closure functions data provider for multi thread execution
126+
*
127+
* @return array
128+
* @SuppressWarnings(PHPMD.ExitExpression)
129+
*/
130+
public function successFunctionsProvider(): array
131+
{
132+
return [
133+
'more_threads_than_functions' => [
134+
'user_functions' => [
135+
// @codingStandardsIgnoreStart
136+
function () {
137+
exit(0);
138+
},
139+
function () {
140+
exit(0);
141+
},
142+
function () {
143+
exit(0);
144+
},
145+
// @codingStandardsIgnoreEnd
146+
],
147+
'threads_count' => 4,
148+
],
149+
'less_threads_than_functions' => [
150+
'user_functions' => [
151+
// @codingStandardsIgnoreStart
152+
function () {
153+
exit(0);
154+
},
155+
function () {
156+
exit(0);
157+
},
158+
function () {
159+
exit(0);
160+
},
161+
// @codingStandardsIgnoreEnd
162+
],
163+
'threads_count' => 2,
164+
],
165+
'equal_threads_and_functions' => [
166+
'user_functions' => [
167+
// @codingStandardsIgnoreStart
168+
function () {
169+
exit(0);
170+
},
171+
function () {
172+
exit(0);
173+
},
174+
function () {
175+
exit(0);
176+
},
177+
// @codingStandardsIgnoreEnd
178+
],
179+
'threads_count' => 3,
180+
],
181+
];
182+
}
183+
}

0 commit comments

Comments
 (0)