77
88use Magento \Framework \Cache \InvalidateLogger ;
99
10+ /**
11+ * Class PurgeCache
12+ */
1013class PurgeCache
1114{
1215 const HEADER_X_MAGENTO_TAGS_PATTERN = 'X-Magento-Tags-Pattern ' ;
@@ -26,6 +29,18 @@ class PurgeCache
2629 */
2730 private $ logger ;
2831
32+ /**
33+ * Batch size of the purge request.
34+ *
35+ * Based on default Varnish 4 http_req_hdr_len size minus a 512 bytes margin for method,
36+ * header name, line feeds etc.
37+ *
38+ * @see https://varnish-cache.org/docs/4.1/reference/varnishd.html
39+ *
40+ * @var int
41+ */
42+ private $ requestSize = 7680 ;
43+
2944 /**
3045 * Constructor
3146 *
@@ -44,18 +59,65 @@ public function __construct(
4459 }
4560
4661 /**
47- * Send curl purge request
48- * to invalidate cache by tags pattern
62+ * Send curl purge request to invalidate cache by tags pattern
4963 *
5064 * @param string $tagsPattern
5165 * @return bool Return true if successful; otherwise return false
5266 */
5367 public function sendPurgeRequest ($ tagsPattern )
5468 {
69+ $ successful = true ;
5570 $ socketAdapter = $ this ->socketAdapterFactory ->create ();
5671 $ servers = $ this ->cacheServer ->getUris ();
57- $ headers = [self ::HEADER_X_MAGENTO_TAGS_PATTERN => $ tagsPattern ];
5872 $ socketAdapter ->setOptions (['timeout ' => 10 ]);
73+
74+ $ formattedTagsChunks = $ this ->splitTags ($ tagsPattern );
75+ foreach ($ formattedTagsChunks as $ formattedTagsChunk ) {
76+ if (!$ this ->sendPurgeRequestToServers ($ socketAdapter , $ servers , $ formattedTagsChunk )) {
77+ $ successful = false ;
78+ }
79+ }
80+
81+ return $ successful ;
82+ }
83+
84+ /**
85+ * Split tags by batches
86+ *
87+ * @param string $tagsPattern
88+ * @return \Generator
89+ */
90+ private function splitTags ($ tagsPattern )
91+ {
92+ $ tagsBatchSize = 0 ;
93+ $ formattedTagsChunk = [];
94+ $ formattedTags = explode ('| ' , $ tagsPattern );
95+ foreach ($ formattedTags as $ formattedTag ) {
96+ if ($ tagsBatchSize + strlen ($ formattedTag ) > $ this ->requestSize - count ($ formattedTagsChunk ) - 1 ) {
97+ yield implode ('| ' , array_unique ($ formattedTagsChunk ));
98+ $ formattedTagsChunk = [];
99+ $ tagsBatchSize = 0 ;
100+ }
101+
102+ $ tagsBatchSize += strlen ($ formattedTag );
103+ $ formattedTagsChunk [] = $ formattedTag ;
104+ }
105+ if (!empty ($ formattedTagsChunk )) {
106+ yield implode ('| ' , array_unique ($ formattedTagsChunk ));
107+ }
108+ }
109+
110+ /**
111+ * Send curl purge request to servers to invalidate cache by tags pattern
112+ *
113+ * @param \Zend\Http\Client\Adapter\Socket $socketAdapter
114+ * @param \Zend\Uri\Uri[] $servers
115+ * @param string $formattedTagsChunk
116+ * @return bool Return true if successful; otherwise return false
117+ */
118+ private function sendPurgeRequestToServers ($ socketAdapter , $ servers , $ formattedTagsChunk )
119+ {
120+ $ headers = [self ::HEADER_X_MAGENTO_TAGS_PATTERN => $ formattedTagsChunk ];
59121 foreach ($ servers as $ server ) {
60122 $ headers ['Host ' ] = $ server ->getHost ();
61123 try {
@@ -69,12 +131,11 @@ public function sendPurgeRequest($tagsPattern)
69131 $ socketAdapter ->read ();
70132 $ socketAdapter ->close ();
71133 } catch (\Exception $ e ) {
72- $ this ->logger ->critical ($ e ->getMessage (), compact ('server ' , 'tagsPattern ' ));
134+ $ this ->logger ->critical ($ e ->getMessage (), compact ('server ' , 'formattedTagsChunk ' ));
73135 return false ;
74136 }
75137 }
76-
77- $ this ->logger ->execute (compact ('servers ' , 'tagsPattern ' ));
138+ $ this ->logger ->execute (compact ('servers ' , 'formattedTagsChunk ' ));
78139 return true ;
79140 }
80141}
0 commit comments