Skip to content

Commit 05d0f99

Browse files
committed
ACP2E-3902: [Cloud] Sitemap generation never ends
1 parent f1adb44 commit 05d0f99

File tree

11 files changed

+2728
-5
lines changed

11 files changed

+2728
-5
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Sitemap\Model\Batch;
9+
10+
use Magento\Framework\App\Area;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Sitemap\Model\EmailNotification as SitemapEmail;
13+
use Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory;
14+
use Magento\Store\Model\App\Emulation;
15+
use Magento\Store\Model\ScopeInterface;
16+
use Psr\Log\LoggerInterface;
17+
18+
/**
19+
* Memory-optimized sitemap observer for scheduled generation using batch processing
20+
*/
21+
class Observer
22+
{
23+
/**
24+
* Enable/disable configuration
25+
*/
26+
private const XML_PATH_GENERATION_ENABLED = 'sitemap/generate/enabled';
27+
28+
/**
29+
* 'Send error emails to' configuration
30+
*/
31+
private const XML_PATH_ERROR_RECIPIENT = 'sitemap/generate/error_email';
32+
33+
/**
34+
* Core store config
35+
*
36+
* @var ScopeConfigInterface
37+
*/
38+
private ScopeConfigInterface $scopeConfig;
39+
40+
/**
41+
* @var CollectionFactory
42+
*/
43+
private CollectionFactory $collectionFactory;
44+
45+
/**
46+
* @var SitemapFactory
47+
*/
48+
private SitemapFactory $batchSitemapFactory;
49+
50+
/**
51+
* @var SitemapEmail
52+
*/
53+
private SitemapEmail $emailNotification;
54+
55+
/**
56+
* @var Emulation
57+
*/
58+
private Emulation $appEmulation;
59+
60+
/**
61+
* @var LoggerInterface
62+
*/
63+
private LoggerInterface $logger;
64+
65+
/**
66+
* Observer constructor.
67+
*
68+
* @param ScopeConfigInterface $scopeConfig
69+
* @param CollectionFactory $collectionFactory
70+
* @param SitemapFactory $batchSitemapFactory
71+
* @param SitemapEmail $emailNotification
72+
* @param Emulation $appEmulation
73+
* @param LoggerInterface $logger
74+
*/
75+
public function __construct(
76+
ScopeConfigInterface $scopeConfig,
77+
CollectionFactory $collectionFactory,
78+
SitemapFactory $batchSitemapFactory,
79+
SitemapEmail $emailNotification,
80+
Emulation $appEmulation,
81+
LoggerInterface $logger
82+
) {
83+
$this->scopeConfig = $scopeConfig;
84+
$this->collectionFactory = $collectionFactory;
85+
$this->batchSitemapFactory = $batchSitemapFactory;
86+
$this->emailNotification = $emailNotification;
87+
$this->appEmulation = $appEmulation;
88+
$this->logger = $logger;
89+
}
90+
91+
/**
92+
* Generate sitemaps using memory-optimized batch processing
93+
*
94+
* @return void
95+
* @throws \Exception
96+
*/
97+
public function scheduledGenerateSitemaps(): void
98+
{
99+
$errors = [];
100+
$recipient = $this->scopeConfig->getValue(
101+
self::XML_PATH_ERROR_RECIPIENT,
102+
ScopeInterface::SCOPE_STORE
103+
);
104+
105+
if (!$this->scopeConfig->isSetFlag(
106+
self::XML_PATH_GENERATION_ENABLED,
107+
ScopeInterface::SCOPE_STORE
108+
)) {
109+
return;
110+
}
111+
112+
$collection = $this->collectionFactory->create();
113+
$this->logger->info(sprintf('Found %d sitemap(s) to generate using batch processing', $collection->getSize()));
114+
115+
/** @var \Magento\Sitemap\Model\Sitemap $sitemap */
116+
foreach ($collection as $sitemapData) {
117+
try {
118+
$storeId = $sitemapData->getStoreId();
119+
120+
$this->appEmulation->startEnvironmentEmulation(
121+
$storeId,
122+
Area::AREA_FRONTEND,
123+
true
124+
);
125+
126+
$batchSitemap = $this->batchSitemapFactory->create();
127+
$batchSitemap->setData($sitemapData->getData());
128+
129+
$batchSitemap->generateXml();
130+
131+
$this->logger->info(
132+
"Sitemap generated successfully for store {$storeId}: " . $batchSitemap->getSitemapFilename()
133+
);
134+
135+
} catch (\Exception $e) {
136+
$errors[] = $e->getMessage();
137+
$this->logger->error($e->getMessage(), ['exception' => $e]);
138+
} finally {
139+
$this->appEmulation->stopEnvironmentEmulation();
140+
}
141+
}
142+
143+
if ($errors && $recipient) {
144+
$this->emailNotification->sendErrors($errors);
145+
}
146+
}
147+
}

0 commit comments

Comments
 (0)