66namespace Magento \CacheInvalidate \Model ;
77
88use Magento \Framework \Cache \InvalidateLogger ;
9+ use Magento \PageCache \Model \Cache \Server ;
10+ use Laminas \Http \Client \Adapter \Socket ;
11+ use Laminas \Uri \Uri ;
912
1013/**
11- * PurgeCache model
14+ * Invalidate external HTTP cache(s) based on tag pattern
1215 */
1316class PurgeCache
1417{
1518 const HEADER_X_MAGENTO_TAGS_PATTERN = 'X-Magento-Tags-Pattern ' ;
1619
1720 /**
18- * @var \Magento\PageCache\Model\Cache\ Server
21+ * @var Server
1922 */
2023 protected $ cacheServer ;
2124
2225 /**
23- * @var \Magento\CacheInvalidate\Model\ SocketFactory
26+ * @var SocketFactory
2427 */
2528 protected $ socketAdapterFactory ;
2629
@@ -39,39 +42,46 @@ class PurgeCache
3942 *
4043 * @var int
4144 */
42- private $ requestSize = 7680 ;
45+ private $ maxHeaderSize ;
4346
4447 /**
4548 * Constructor
4649 *
47- * @param \Magento\PageCache\Model\Cache\ Server $cacheServer
48- * @param \Magento\CacheInvalidate\Model\ SocketFactory $socketAdapterFactory
50+ * @param Server $cacheServer
51+ * @param SocketFactory $socketAdapterFactory
4952 * @param InvalidateLogger $logger
53+ * @param int $maxHeaderSize
5054 */
5155 public function __construct (
52- \Magento \PageCache \Model \Cache \Server $ cacheServer ,
53- \Magento \CacheInvalidate \Model \SocketFactory $ socketAdapterFactory ,
54- InvalidateLogger $ logger
56+ Server $ cacheServer ,
57+ SocketFactory $ socketAdapterFactory ,
58+ InvalidateLogger $ logger ,
59+ int $ maxHeaderSize = 7680
5560 ) {
5661 $ this ->cacheServer = $ cacheServer ;
5762 $ this ->socketAdapterFactory = $ socketAdapterFactory ;
5863 $ this ->logger = $ logger ;
64+ $ this ->maxHeaderSize = $ maxHeaderSize ;
5965 }
6066
6167 /**
6268 * Send curl purge request to invalidate cache by tags pattern
6369 *
64- * @param string $tagsPattern
70+ * @param array| string $tags
6571 * @return bool Return true if successful; otherwise return false
6672 */
67- public function sendPurgeRequest ($ tagsPattern )
73+ public function sendPurgeRequest ($ tags )
6874 {
75+ if (is_string ($ tags )) {
76+ $ tags = [$ tags ];
77+ }
78+
6979 $ successful = true ;
7080 $ socketAdapter = $ this ->socketAdapterFactory ->create ();
7181 $ servers = $ this ->cacheServer ->getUris ();
7282 $ socketAdapter ->setOptions (['timeout ' => 10 ]);
7383
74- $ formattedTagsChunks = $ this ->splitTags ( $ tagsPattern );
84+ $ formattedTagsChunks = $ this ->chunkTags ( $ tags );
7585 foreach ($ formattedTagsChunks as $ formattedTagsChunk ) {
7686 if (!$ this ->sendPurgeRequestToServers ($ socketAdapter , $ servers , $ formattedTagsChunk )) {
7787 $ successful = false ;
@@ -82,24 +92,24 @@ public function sendPurgeRequest($tagsPattern)
8292 }
8393
8494 /**
85- * Split tags by batches
95+ * Split tags into batches to suit Varnish max. header size
8696 *
87- * @param string $tagsPattern
97+ * @param array $tags
8898 * @return \Generator
8999 */
90- private function splitTags ( $ tagsPattern )
100+ private function chunkTags ( array $ tags ): \ Generator
91101 {
92- $ tagsBatchSize = 0 ;
102+ $ currentBatchSize = 0 ;
93103 $ formattedTagsChunk = [];
94- $ formattedTags = explode ( ' | ' , $ tagsPattern );
95- foreach ( $ formattedTags as $ formattedTag ) {
96- if ($ tagsBatchSize + strlen ($ formattedTag ) > $ this -> requestSize - count ($ formattedTagsChunk ) - 1 ) {
104+ foreach ( $ tags as $ formattedTag ) {
105+ // Check if (currentBatchSize + length of next tag + number of pipe delimiters) would exceed header size.
106+ if ($ currentBatchSize + strlen ($ formattedTag ) + count ($ formattedTagsChunk ) > $ this -> maxHeaderSize ) {
97107 yield implode ('| ' , $ formattedTagsChunk );
98108 $ formattedTagsChunk = [];
99- $ tagsBatchSize = 0 ;
109+ $ currentBatchSize = 0 ;
100110 }
101111
102- $ tagsBatchSize += strlen ($ formattedTag );
112+ $ currentBatchSize += strlen ($ formattedTag );
103113 $ formattedTagsChunk [] = $ formattedTag ;
104114 }
105115 if (!empty ($ formattedTagsChunk )) {
@@ -110,12 +120,12 @@ private function splitTags($tagsPattern)
110120 /**
111121 * Send curl purge request to servers to invalidate cache by tags pattern
112122 *
113- * @param \Laminas\Http\Client\Adapter\ Socket $socketAdapter
114- * @param \Laminas\Uri\ Uri[] $servers
123+ * @param Socket $socketAdapter
124+ * @param Uri[] $servers
115125 * @param string $formattedTagsChunk
116126 * @return bool Return true if successful; otherwise return false
117127 */
118- private function sendPurgeRequestToServers ($ socketAdapter , $ servers , $ formattedTagsChunk )
128+ private function sendPurgeRequestToServers (Socket $ socketAdapter , array $ servers , string $ formattedTagsChunk ): bool
119129 {
120130 $ headers = [self ::HEADER_X_MAGENTO_TAGS_PATTERN => $ formattedTagsChunk ];
121131 $ unresponsiveServerError = [];
0 commit comments