Skip to content

Commit 92fab51

Browse files
committed
Implement Asynchronous Operation status change based on a lookup key
1 parent 55af84f commit 92fab51

File tree

17 files changed

+215
-126
lines changed

17 files changed

+215
-126
lines changed

app/code/Magento/AsynchronousOperations/Model/BulkManagement.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ public function scheduleBulk($bulkUuid, array $operations, $description, $userId
140140
public function retryBulk($bulkUuid, array $errorCodes)
141141
{
142142
$metadata = $this->metadataPool->getMetadata(BulkSummaryInterface::class);
143-
$connection = $this->resourceConnection->getConnectionByName($metadata->getEntityConnectionName());
144143

144+
$connection = $this->resourceConnection->getConnectionByName($metadata->getEntityConnectionName());
145145
/** @var \Magento\AsynchronousOperations\Model\ResourceModel\Operation[] $retriablyFailedOperations */
146146
$retriablyFailedOperations = $this->operationCollectionFactory->create()
147147
->addFieldToFilter('error_code', ['in' => $errorCodes])
@@ -157,23 +157,27 @@ public function retryBulk($bulkUuid, array $errorCodes)
157157
/** @var OperationInterface $operation */
158158
foreach ($retriablyFailedOperations as $operation) {
159159
if ($currentBatchSize === $maxBatchSize) {
160+
$whereCondition = $connection->quoteInto('operation_key IN (?)', $operationIds)
161+
. " AND "
162+
. $connection->quoteInto('bulk_uuid = ?', $bulkUuid);
160163
$connection->delete(
161164
$this->resourceConnection->getTableName('magento_operation'),
162-
$connection->quoteInto('id IN (?)', $operationIds)
165+
$whereCondition
163166
);
164167
$operationIds = [];
165168
$currentBatchSize = 0;
166169
}
167170
$currentBatchSize++;
168171
$operationIds[] = $operation->getId();
169-
// Rescheduled operations must be put in queue in 'open' state (i.e. without ID)
170-
$operation->setId(null);
171172
}
172173
// remove operations from the last batch
173174
if (!empty($operationIds)) {
175+
$whereCondition = $connection->quoteInto('operation_key IN (?)', $operationIds)
176+
. " AND "
177+
. $connection->quoteInto('bulk_uuid = ?', $bulkUuid);
174178
$connection->delete(
175179
$this->resourceConnection->getTableName('magento_operation'),
176-
$connection->quoteInto('id IN (?)', $operationIds)
180+
$whereCondition
177181
);
178182
}
179183

app/code/Magento/AsynchronousOperations/Model/MassSchedule.php

-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use Magento\AsynchronousOperations\Api\Data\AsyncResponseInterfaceFactory;
1212
use Magento\AsynchronousOperations\Api\Data\ItemStatusInterface;
1313
use Magento\AsynchronousOperations\Api\Data\ItemStatusInterfaceFactory;
14-
use Magento\AsynchronousOperations\Model\ResourceModel\Operation\OperationRepository;
1514
use Magento\Authorization\Model\UserContextInterface;
1615
use Magento\Framework\Bulk\BulkManagementInterface;
1716
use Magento\Framework\DataObject\IdentityGeneratorInterface;
@@ -144,7 +143,6 @@ public function publishMass($topicName, array $entitiesArray, $groupId = null, $
144143
foreach ($entitiesArray as $key => $entityParams) {
145144
/** @var \Magento\AsynchronousOperations\Api\Data\ItemStatusInterface $requestItem */
146145
$requestItem = $this->itemStatusInterfaceFactory->create();
147-
148146
try {
149147
$operation = $this->operationRepository->create($topicName, $entityParams, $groupId, $key);
150148
$operations[] = $operation;

app/code/Magento/AsynchronousOperations/Model/OperationManagement.php

+24-18
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@
77
namespace Magento\AsynchronousOperations\Model;
88

99
use Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory;
10-
use Magento\Framework\EntityManager\EntityManager;
10+
use Magento\Framework\App\ResourceConnection;
11+
use Psr\Log\LoggerInterface;
12+
use Magento\Framework\Bulk\OperationManagementInterface;
1113

1214
/**
1315
* Class for managing Bulk Operations
1416
*/
15-
class OperationManagement implements \Magento\Framework\Bulk\OperationManagementInterface
17+
class OperationManagement implements OperationManagementInterface
1618
{
1719
/**
18-
* @var EntityManager
20+
* @var ResourceConnection
1921
*/
20-
private $entityManager;
22+
private $connection;
2123

2224
/**
2325
* @var OperationInterfaceFactory
@@ -32,40 +34,44 @@ class OperationManagement implements \Magento\Framework\Bulk\OperationManagement
3234
/**
3335
* OperationManagement constructor.
3436
*
35-
* @param EntityManager $entityManager
3637
* @param OperationInterfaceFactory $operationFactory
37-
* @param \Psr\Log\LoggerInterface $logger
38+
* @param LoggerInterface $logger
39+
* @param ResourceConnection $connection
3840
*/
3941
public function __construct(
40-
EntityManager $entityManager,
4142
OperationInterfaceFactory $operationFactory,
42-
\Psr\Log\LoggerInterface $logger
43+
LoggerInterface $logger,
44+
ResourceConnection $connection
4345
) {
44-
$this->entityManager = $entityManager;
4546
$this->operationFactory = $operationFactory;
4647
$this->logger = $logger;
48+
$this->connection = $connection;
4749
}
4850

4951
/**
5052
* @inheritDoc
5153
*/
5254
public function changeOperationStatus(
53-
$operationId,
55+
$bulkUuid,
56+
$operationKey,
5457
$status,
5558
$errorCode = null,
5659
$message = null,
5760
$data = null,
5861
$resultData = null
5962
) {
6063
try {
61-
$operationEntity = $this->operationFactory->create();
62-
$this->entityManager->load($operationEntity, $operationId);
63-
$operationEntity->setErrorCode($errorCode);
64-
$operationEntity->setStatus($status);
65-
$operationEntity->setResultMessage($message);
66-
$operationEntity->setSerializedData($data);
67-
$operationEntity->setResultSerializedData($resultData);
68-
$this->entityManager->save($operationEntity);
64+
$connection = $this->connection->getConnection();
65+
$table = $this->connection->getTableName('magento_operation');
66+
$bind = [
67+
'error_code' => $errorCode,
68+
'status' => $status,
69+
'result_message' => $message,
70+
'serialized_data' => $data,
71+
'result_serialized_data' => $resultData
72+
];
73+
$where = ['bulk_uuid = ?' => $bulkUuid, 'operation_key = ?' => $operationKey];
74+
$connection->update($table, $bind, $where);
6975
} catch (\Exception $exception) {
7076
$this->logger->critical($exception->getMessage());
7177
return false;

app/code/Magento/AsynchronousOperations/Model/OperationProcessor.php

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ public function process(string $encodedMessage)
163163

164164
$serializedData = (isset($errorCode)) ? $operation->getSerializedData() : null;
165165
$this->operationManagement->changeOperationStatus(
166+
$operation->getBulkUuid(),
166167
$operation->getId(),
167168
$status,
168169
$errorCode,

app/code/Magento/AsynchronousOperations/Model/ResourceModel/Operation.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66

77
namespace Magento\AsynchronousOperations\Model\ResourceModel;
88

9+
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
10+
911
/**
1012
* Resource class for Bulk Operations
1113
*/
12-
class Operation extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
14+
class Operation extends AbstractDb
1315
{
1416

1517
public const TABLE_NAME = "magento_operation";

app/code/Magento/AsynchronousOperations/Model/ResourceModel/Operation/OperationRepository.php

+11-6
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6-
76
declare(strict_types=1);
87

98
namespace Magento\AsynchronousOperations\Model\ResourceModel\Operation;
109

1110
use Magento\AsynchronousOperations\Api\Data\OperationInterface;
1211
use Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory;
1312
use Magento\AsynchronousOperations\Model\OperationRepositoryInterface;
13+
use Magento\Framework\Exception\LocalizedException;
1414
use Magento\Framework\MessageQueue\MessageValidator;
1515
use Magento\Framework\MessageQueue\MessageEncoder;
1616
use Magento\Framework\Serialize\Serializer\Json;
@@ -73,11 +73,13 @@ public function __construct(
7373
* @param string $topicName
7474
* @param array $entityParams
7575
* @param string $groupId
76+
* @param string $operationId
7677
* @return OperationInterface
78+
* @throws LocalizedException
7779
* @deprecated No longer used.
7880
* @see create()
7981
*/
80-
public function createByTopic($topicName, $entityParams, $groupId)
82+
public function createByTopic($topicName, $entityParams, $groupId, $operationId)
8183
{
8284
$this->messageValidator->validate($topicName, $entityParams);
8385
$encodedMessage = $this->messageEncoder->encode($topicName, $entityParams);
@@ -89,10 +91,11 @@ public function createByTopic($topicName, $entityParams, $groupId)
8991
];
9092
$data = [
9193
'data' => [
92-
OperationInterface::BULK_ID => $groupId,
93-
OperationInterface::TOPIC_NAME => $topicName,
94+
OperationInterface::ID => $operationId,
95+
OperationInterface::BULK_ID => $groupId,
96+
OperationInterface::TOPIC_NAME => $topicName,
9497
OperationInterface::SERIALIZED_DATA => $this->jsonSerializer->serialize($serializedData),
95-
OperationInterface::STATUS => OperationInterface::STATUS_TYPE_OPEN,
98+
OperationInterface::STATUS => OperationInterface::STATUS_TYPE_OPEN,
9699
],
97100
];
98101

@@ -103,9 +106,11 @@ public function createByTopic($topicName, $entityParams, $groupId)
103106

104107
/**
105108
* @inheritDoc
109+
*
110+
* @throws LocalizedException
106111
*/
107112
public function create($topicName, $entityParams, $groupId, $operationId): OperationInterface
108113
{
109-
return $this->createByTopic($topicName, $entityParams, $groupId);
114+
return $this->createByTopic($topicName, $entityParams, $groupId, $operationId);
110115
}
111116
}

app/code/Magento/AsynchronousOperations/Test/Unit/Model/BulkManagementTest.php

+23-10
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public function testRetryBulk()
196196
$bulkUuid = 'bulk-001';
197197
$errorCodes = ['errorCode'];
198198
$connectionName = 'default';
199-
$operationId = 1;
199+
$operationId = 0;
200200
$operationTable = 'magento_operation';
201201
$topicName = 'topic.name';
202202
$metadata = $this->getMockForAbstractClass(EntityMetadataInterface::class);
@@ -216,13 +216,20 @@ public function testRetryBulk()
216216
$operationCollection->expects($this->once())->method('getItems')->willReturn([$operation]);
217217
$connection->expects($this->once())->method('beginTransaction')->willReturnSelf();
218218
$operation->expects($this->once())->method('getId')->willReturn($operationId);
219-
$operation->expects($this->once())->method('setId')->with(null)->willReturnSelf();
220219
$this->resourceConnection->expects($this->once())
221220
->method('getTableName')->with($operationTable)->willReturn($operationTable);
221+
$connection->expects($this->at(1))
222+
->method('quoteInto')
223+
->with('operation_key IN (?)', [$operationId])
224+
->willReturn('operation_key IN (' . $operationId . ')');
225+
$connection->expects($this->at(2))
226+
->method('quoteInto')
227+
->with('bulk_uuid = ?', $bulkUuid)
228+
->willReturn("bulk_uuid = '$bulkUuid'");
222229
$connection->expects($this->once())
223-
->method('quoteInto')->with('id IN (?)', [$operationId])->willReturn('id IN (' . $operationId . ')');
224-
$connection->expects($this->once())
225-
->method('delete')->with($operationTable, 'id IN (' . $operationId . ')')->willReturn(1);
230+
->method('delete')
231+
->with($operationTable, 'operation_key IN (' . $operationId . ') AND bulk_uuid = \'' . $bulkUuid . '\'')
232+
->willReturn(1);
226233
$connection->expects($this->once())->method('commit')->willReturnSelf();
227234
$operation->expects($this->once())->method('getTopicName')->willReturn($topicName);
228235
$this->publisher->expects($this->once())->method('publish')->with($topicName, [$operation])->willReturn(null);
@@ -239,7 +246,7 @@ public function testRetryBulkWithException()
239246
$bulkUuid = 'bulk-001';
240247
$errorCodes = ['errorCode'];
241248
$connectionName = 'default';
242-
$operationId = 1;
249+
$operationId = 0;
243250
$operationTable = 'magento_operation';
244251
$exceptionMessage = 'Exception message';
245252
$metadata = $this->getMockForAbstractClass(EntityMetadataInterface::class);
@@ -259,13 +266,19 @@ public function testRetryBulkWithException()
259266
$operationCollection->expects($this->once())->method('getItems')->willReturn([$operation]);
260267
$connection->expects($this->once())->method('beginTransaction')->willReturnSelf();
261268
$operation->expects($this->once())->method('getId')->willReturn($operationId);
262-
$operation->expects($this->once())->method('setId')->with(null)->willReturnSelf();
263269
$this->resourceConnection->expects($this->once())
264270
->method('getTableName')->with($operationTable)->willReturn($operationTable);
271+
$connection->expects($this->at(1))
272+
->method('quoteInto')
273+
->with('operation_key IN (?)', [$operationId])
274+
->willReturn('operation_key IN (' . $operationId . ')');
275+
$connection->expects($this->at(2))
276+
->method('quoteInto')
277+
->with('bulk_uuid = ?', $bulkUuid)
278+
->willReturn("bulk_uuid = '$bulkUuid'");
265279
$connection->expects($this->once())
266-
->method('quoteInto')->with('id IN (?)', [$operationId])->willReturn('id IN (' . $operationId . ')');
267-
$connection->expects($this->once())
268-
->method('delete')->with($operationTable, 'id IN (' . $operationId . ')')
280+
->method('delete')
281+
->with($operationTable, 'operation_key IN (' . $operationId . ') AND bulk_uuid = \'' . $bulkUuid . '\'')
269282
->willThrowException(new \Exception($exceptionMessage));
270283
$connection->expects($this->once())->method('rollBack')->willReturnSelf();
271284
$this->logger->expects($this->once())->method('critical')->with($exceptionMessage);

0 commit comments

Comments
 (0)