Skip to content

Commit e212301

Browse files
author
Matthew O'Loughlin
committed
GH-26255: Refactor CacheInvalidate sendPurgeRequest to allow correct purge batching, regardless of
the size and content of provided tag pattern.
1 parent 3e23510 commit e212301

File tree

5 files changed

+27
-19
lines changed

5 files changed

+27
-19
lines changed

app/code/Magento/CacheInvalidate/Model/PurgeCache.php

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,39 +39,46 @@ class PurgeCache
3939
*
4040
* @var int
4141
*/
42-
private $requestSize = 7680;
42+
private $requestSize;
4343

4444
/**
4545
* Constructor
4646
*
4747
* @param \Magento\PageCache\Model\Cache\Server $cacheServer
4848
* @param \Magento\CacheInvalidate\Model\SocketFactory $socketAdapterFactory
4949
* @param InvalidateLogger $logger
50+
* @param int $maxHeaderSize
5051
*/
5152
public function __construct(
5253
\Magento\PageCache\Model\Cache\Server $cacheServer,
5354
\Magento\CacheInvalidate\Model\SocketFactory $socketAdapterFactory,
54-
InvalidateLogger $logger
55+
InvalidateLogger $logger,
56+
$maxHeaderSize = 7680
5557
) {
5658
$this->cacheServer = $cacheServer;
5759
$this->socketAdapterFactory = $socketAdapterFactory;
5860
$this->logger = $logger;
61+
$this->requestSize = $maxHeaderSize;
5962
}
6063

6164
/**
6265
* Send curl purge request to invalidate cache by tags pattern
6366
*
64-
* @param string $tagsPattern
67+
* @param array|string $tags
6568
* @return bool Return true if successful; otherwise return false
6669
*/
67-
public function sendPurgeRequest($tagsPattern)
70+
public function sendPurgeRequest($tags)
6871
{
72+
if (!is_string($tags)) {
73+
$tags = [$tags];
74+
}
75+
6976
$successful = true;
7077
$socketAdapter = $this->socketAdapterFactory->create();
7178
$servers = $this->cacheServer->getUris();
7279
$socketAdapter->setOptions(['timeout' => 10]);
7380

74-
$formattedTagsChunks = $this->splitTags($tagsPattern);
81+
$formattedTagsChunks = $this->chunkTags($tags);
7582
foreach ($formattedTagsChunks as $formattedTagsChunk) {
7683
if (!$this->sendPurgeRequestToServers($socketAdapter, $servers, $formattedTagsChunk)) {
7784
$successful = false;
@@ -82,24 +89,24 @@ public function sendPurgeRequest($tagsPattern)
8289
}
8390

8491
/**
85-
* Split tags by batches
92+
* Split tags into batches to suit Varnish max. header size
8693
*
87-
* @param string $tagsPattern
94+
* @param array $tags
8895
* @return \Generator
8996
*/
90-
private function splitTags($tagsPattern)
97+
private function chunkTags($tags)
9198
{
92-
$tagsBatchSize = 0;
99+
$currentBatchSize = 0;
93100
$formattedTagsChunk = [];
94-
$formattedTags = explode('|', $tagsPattern);
95-
foreach ($formattedTags as $formattedTag) {
96-
if ($tagsBatchSize + strlen($formattedTag) > $this->requestSize - count($formattedTagsChunk) - 1) {
101+
foreach ($tags as $formattedTag) {
102+
// Check if (currentBatchSize + length of next tag + number of pipe delimiters) would exceed header size.
103+
if ($currentBatchSize + strlen($formattedTag) + count($formattedTagsChunk) > $this->requestSize) {
97104
yield implode('|', $formattedTagsChunk);
98105
$formattedTagsChunk = [];
99-
$tagsBatchSize = 0;
106+
$currentBatchSize = 0;
100107
}
101108

102-
$tagsBatchSize += strlen($formattedTag);
109+
$currentBatchSize += strlen($formattedTag);
103110
$formattedTagsChunk[] = $formattedTag;
104111
}
105112
if (!empty($formattedTagsChunk)) {

app/code/Magento/CacheInvalidate/Observer/FlushAllCacheObserver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function __construct(
4343
public function execute(\Magento\Framework\Event\Observer $observer)
4444
{
4545
if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled()) {
46-
$this->purgeCache->sendPurgeRequest('.*');
46+
$this->purgeCache->sendPurgeRequest(['.*']);
4747
}
4848
}
4949
}

app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function execute(\Magento\Framework\Event\Observer $observer)
6262
$tags[] = sprintf($pattern, $tag);
6363
}
6464
if (!empty($tags)) {
65-
$this->purgeCache->sendPurgeRequest(implode('|', array_unique($tags)));
65+
$this->purgeCache->sendPurgeRequest(array_unique($tags));
6666
}
6767
}
6868
}

app/code/Magento/CacheInvalidate/Test/Unit/Model/PurgeCacheTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ protected function setUp()
5353
public function testSendPurgeRequest($hosts)
5454
{
5555
$uris = [];
56+
/** @var array $host */
5657
foreach ($hosts as $host) {
5758
$port = isset($host['port']) ? $host['port'] : \Magento\PageCache\Model\Cache\Server::DEFAULT_PORT;
5859
$uris[] = UriFactory::factory('')->setHost($host['host'])
@@ -81,7 +82,7 @@ public function testSendPurgeRequest($hosts)
8182
$this->loggerMock->expects($this->once())
8283
->method('execute');
8384

84-
$this->assertTrue($this->model->sendPurgeRequest('tags'));
85+
$this->assertTrue($this->model->sendPurgeRequest(['tags']));
8586
}
8687

8788
/**
@@ -119,6 +120,6 @@ public function testSendPurgeRequestWithException()
119120
$this->loggerMock->expects($this->once())
120121
->method('critical');
121122

122-
$this->assertFalse($this->model->sendPurgeRequest('tags'));
123+
$this->assertFalse($this->model->sendPurgeRequest(['tags']));
123124
}
124125
}

app/code/Magento/CacheInvalidate/Test/Unit/Observer/FlushAllCacheObserverTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function testFlushAllCache()
4747
$this->returnValue(\Magento\PageCache\Model\Config::VARNISH)
4848
);
4949

50-
$this->purgeCache->expects($this->once())->method('sendPurgeRequest')->with('.*');
50+
$this->purgeCache->expects($this->once())->method('sendPurgeRequest')->with(['.*']);
5151
$this->model->execute($this->observerMock);
5252
}
5353
}

0 commit comments

Comments
 (0)