I'm trying to move my heavy treatment to Messenger.
It works but I would like to show a percentage of progress to my users. I created a DownloadTask entity and I try to update it during the process but it doesn't work. My entity is not updated in the database.
Do you have any ideas?
I'm still learning, so I hope my code won't hurt your eyes too much.
<?php
namespace App\MessageHandler;
use App\Message\GetSellerList;
use App\Repository\DownloadTaskRepository;
use App\Service\EbayDL;
use Doctrine\DBAL\ConnectionException;
use Doctrine\ORM\EntityManagerInterface;
use DTS\eBaySDK\Trading\Types\GetSellerListResponseType;
use GuzzleHttp\Promise;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class GetSellerListHandler implements MessageHandlerInterface
{
/**
* @var EbayDL
*/
private $ebayDL;
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var \App\Entity\DownloadTask
*/
private $task;
/**
* @var DownloadTaskRepository
*/
private $downloadTaskRepository;
public function __construct(EbayDL $ebayDL, EntityManagerInterface $entityManager, DownloadTaskRepository $downloadTaskRepository, LoggerInterface $logger)
{
$this->ebayDL = $ebayDL;
$this->entityManager = $entityManager;
$this->logger = $logger;
$this->downloadTaskRepository = $downloadTaskRepository;
}
/**
* @throws ConnectionException
* @throws \Exception
* @throws \Throwable
*/
public function __invoke(GetSellerList $getSellerList): void
{
$task = $this->downloadTaskRepository->find($getSellerList->getDownloadTaskId());
$this->clearDatabase();
$listingInfos = $this->ebayDL->getInformation();
$totalNumberOfPages = $listingInfos['totalNumberOfPages'];
$promises = (function () use ($totalNumberOfPages) {
for ($page = 1; $page <= $totalNumberOfPages; ++$page) {
yield $this->ebayDL->getProductsByPageAsync($page);
}
})();
$eachPromise = new Promise\EachPromise($promises, [
'concurrency' => 6,
'fulfilled' => function (GetSellerListResponseType $response): void {
$products = $this->ebayDL->parseSellerListResponse($response);
foreach ($products as $product) {
try {
$this->entityManager->persist($product);
$this->entityManager->flush();
} catch (\Exception $e) {
$this->logger->error('Failed to store a product');
$this->logger->error($e->getMessage());
if (!$this->entityManager->isOpen()) {
// https://stackoverflow.com/questions/14258591/the-entitymanager-is-closed
$this->entityManager = $this->entityManager->create(
$this->entityManager->getConnection(),
$this->entityManager->getConfiguration()
);
}
}
}
},
]);
$eachPromise->promise()->wait();
$this->task
->setProgress(100)
->setCompletedAt(new \DateTime('NOW'));
$this->entityManager->flush();
}
/**
* @throws ConnectionException
* @throws \Doctrine\DBAL\DBALException
*/
private function clearDatabase(): void
{
$connection = $this->entityManager->getConnection();
$connection->beginTransaction();
try {
$connection->query('SET FOREIGN_KEY_CHECKS=0');
$connection->query('DELETE FROM product');
$connection->query('SET FOREIGN_KEY_CHECKS=1');
$connection->commit();
} catch (\Exception $exception) {
$connection->rollback();
}
}
}