6
6
namespace Magento \CacheInvalidate \Model ;
7
7
8
8
use Magento \Framework \Cache \InvalidateLogger ;
9
+ use Magento \PageCache \Model \Cache \Server ;
10
+ use Laminas \Http \Client \Adapter \Socket ;
11
+ use Laminas \Uri \Uri ;
9
12
10
13
/**
11
- * PurgeCache model
14
+ * Invalidate external HTTP cache(s) based on tag pattern
12
15
*/
13
16
class PurgeCache
14
17
{
15
18
const HEADER_X_MAGENTO_TAGS_PATTERN = 'X-Magento-Tags-Pattern ' ;
16
19
17
20
/**
18
- * @var \Magento\PageCache\Model\Cache\ Server
21
+ * @var Server
19
22
*/
20
23
protected $ cacheServer ;
21
24
22
25
/**
23
- * @var \Magento\CacheInvalidate\Model\ SocketFactory
26
+ * @var SocketFactory
24
27
*/
25
28
protected $ socketAdapterFactory ;
26
29
@@ -39,39 +42,46 @@ class PurgeCache
39
42
*
40
43
* @var int
41
44
*/
42
- private $ requestSize = 7680 ;
45
+ private $ maxHeaderSize ;
43
46
44
47
/**
45
48
* Constructor
46
49
*
47
- * @param \Magento\PageCache\Model\Cache\ Server $cacheServer
48
- * @param \Magento\CacheInvalidate\Model\ SocketFactory $socketAdapterFactory
50
+ * @param Server $cacheServer
51
+ * @param SocketFactory $socketAdapterFactory
49
52
* @param InvalidateLogger $logger
53
+ * @param int $maxHeaderSize
50
54
*/
51
55
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
55
60
) {
56
61
$ this ->cacheServer = $ cacheServer ;
57
62
$ this ->socketAdapterFactory = $ socketAdapterFactory ;
58
63
$ this ->logger = $ logger ;
64
+ $ this ->maxHeaderSize = $ maxHeaderSize ;
59
65
}
60
66
61
67
/**
62
68
* Send curl purge request to invalidate cache by tags pattern
63
69
*
64
- * @param string $tagsPattern
70
+ * @param array| string $tags
65
71
* @return bool Return true if successful; otherwise return false
66
72
*/
67
- public function sendPurgeRequest ($ tagsPattern )
73
+ public function sendPurgeRequest ($ tags )
68
74
{
75
+ if (is_string ($ tags )) {
76
+ $ tags = [$ tags ];
77
+ }
78
+
69
79
$ successful = true ;
70
80
$ socketAdapter = $ this ->socketAdapterFactory ->create ();
71
81
$ servers = $ this ->cacheServer ->getUris ();
72
82
$ socketAdapter ->setOptions (['timeout ' => 10 ]);
73
83
74
- $ formattedTagsChunks = $ this ->splitTags ( $ tagsPattern );
84
+ $ formattedTagsChunks = $ this ->chunkTags ( $ tags );
75
85
foreach ($ formattedTagsChunks as $ formattedTagsChunk ) {
76
86
if (!$ this ->sendPurgeRequestToServers ($ socketAdapter , $ servers , $ formattedTagsChunk )) {
77
87
$ successful = false ;
@@ -82,24 +92,24 @@ public function sendPurgeRequest($tagsPattern)
82
92
}
83
93
84
94
/**
85
- * Split tags by batches
95
+ * Split tags into batches to suit Varnish max. header size
86
96
*
87
- * @param string $tagsPattern
97
+ * @param array $tags
88
98
* @return \Generator
89
99
*/
90
- private function splitTags ( $ tagsPattern )
100
+ private function chunkTags ( array $ tags ): \ Generator
91
101
{
92
- $ tagsBatchSize = 0 ;
102
+ $ currentBatchSize = 0 ;
93
103
$ 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 ) {
97
107
yield implode ('| ' , $ formattedTagsChunk );
98
108
$ formattedTagsChunk = [];
99
- $ tagsBatchSize = 0 ;
109
+ $ currentBatchSize = 0 ;
100
110
}
101
111
102
- $ tagsBatchSize += strlen ($ formattedTag );
112
+ $ currentBatchSize += strlen ($ formattedTag );
103
113
$ formattedTagsChunk [] = $ formattedTag ;
104
114
}
105
115
if (!empty ($ formattedTagsChunk )) {
@@ -110,12 +120,12 @@ private function splitTags($tagsPattern)
110
120
/**
111
121
* Send curl purge request to servers to invalidate cache by tags pattern
112
122
*
113
- * @param \Laminas\Http\Client\Adapter\ Socket $socketAdapter
114
- * @param \Laminas\Uri\ Uri[] $servers
123
+ * @param Socket $socketAdapter
124
+ * @param Uri[] $servers
115
125
* @param string $formattedTagsChunk
116
126
* @return bool Return true if successful; otherwise return false
117
127
*/
118
- private function sendPurgeRequestToServers ($ socketAdapter , $ servers , $ formattedTagsChunk )
128
+ private function sendPurgeRequestToServers (Socket $ socketAdapter , array $ servers , string $ formattedTagsChunk ): bool
119
129
{
120
130
$ headers = [self ::HEADER_X_MAGENTO_TAGS_PATTERN => $ formattedTagsChunk ];
121
131
$ unresponsiveServerError = [];
0 commit comments