cancel
Showing results for 
Search instead for 
Did you mean: 

Varnish - Should only clear cache for current domain.

0 Kudos

Varnish - Should only clear cache for current domain.

Feature request from pynej, posted on GitHub Jun 03, 2016

If you set up multiple Magneto installs and varnish and get everything working. When you clear the Page Cache on one site it clears all magneto instances cache. The command passed to varnish should include a host header to allow the vcl file to filter ban's on that header.

This adds the current domain to the purge request.

--- vendor/magento/module-cache-invalidate/Model/PurgeCache.php.old 2016-06-03 14:14:45.320427000 -0400
+++ vendor/magento/module-cache-invalidate/Model/PurgeCache.php 2016-06-03 14:32:58.908971000 -0400
@@ -7,10 +7,12 @@

 use Magento\Framework\Cache\InvalidateLogger;
 use Magento\Framework\App\DeploymentConfig;
+use Magento\Framework\App\RequestInterface;

 class PurgeCache
 {
     const HEADER_X_MAGENTO_TAGS_PATTERN = 'X-Magento-Tags-Pattern';
+    const HEADER_HOST = 'host';

     /**
      * @var \Magento\PageCache\Model\Cache\Server
@@ -28,6 +30,11 @@
     private $logger;

     /**
+     * @var RequestInterface
+     */
+    private $request;
+
+    /**
      * Constructor
      *
      * @param \Magento\PageCache\Model\Cache\Server $cacheServer
@@ -37,11 +44,13 @@
     public function __construct(
         \Magento\PageCache\Model\Cache\Server $cacheServer,
         \Magento\CacheInvalidate\Model\SocketFactory $socketAdapterFactory,
-        InvalidateLogger $logger
+        InvalidateLogger $logger,
+        RequestInterface $request
     ) {
         $this->cacheServer = $cacheServer;
         $this->socketAdapterFactory = $socketAdapterFactory;
         $this->logger = $logger;
+        $this->request = $request;
     }

     /**
@@ -55,7 +64,7 @@
     {
         $socketAdapter = $this->socketAdapterFactory->create();
         $servers = $this->cacheServer->getUris();
-        $headers = [self::HEADER_X_MAGENTO_TAGS_PATTERN => $tagsPattern];
+        $headers = [self::HEADER_X_MAGENTO_TAGS_PATTERN => $tagsPattern, self::HEADER_HOST => $this->request->getHttpHost()];
         $socketAdapter->setOptions(['timeout' => 10]);
         foreach ($servers as $server) {
             try {

Then the vcl files can be updated to optionally filter on the domain.

--- vendor/magento/module-page-cache/etc/varnish4.vcl.old   2016-05-16 16:18:20.000000000 -0400
+++ vendor/magento/module-page-cache/etc/varnish4.vcl   2016-06-03 15:10:56.629687000 -0400
@@ -21,6 +21,8 @@
             return (synth(400, "X-Magento-Tags-Pattern header required"));
         }
         ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
+        # or only for the current domain
+        # ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern + " && obj.http.X-Req-Host == " + req.http.host);
         return (synth(200, "Purged"));
     }

@@ -75,6 +77,8 @@
     if (bereq.url ~ "\.js$" || beresp.http.content-type ~ "text") {
         set beresp.do_gzip = true;
     }
+
+    set beresp.http.X-Req-Host = bereq.http.host;

     # cache only successfully responses and 404s
     if (beresp.status != 200 && beresp.status != 404) {
@@ -123,4 +127,5 @@
     unset resp.http.X-Varnish;
     unset resp.http.Via;
     unset resp.http.Link;
+    unset resp.http.X-Req-Host;
 }

 --- vendor/magento/module-page-cache/etc/varnish3.vcl.old  2016-05-16 16:18:20.000000000 -0400
 +++ vendor/magento/module-page-cache/etc/varnish3.vcl  2016-06-03 15:05:46.033544000 -0400
 @@ -28,6 +28,8 @@
              error 400 "X-Magento-Tags-Pattern header required";
          }
          ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
 +  # or only for the current domain
 +        # ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern + " && obj.http.X-Req-Host == " + req.http.host);
          error 200 "Purged";
      }

 @@ -85,6 +87,8 @@
          set beresp.do_gzip = true;
      }

 +    set beresp.http.X-Req-Host = bereq.http.host;
 +
      # cache only successfully responses and 404s
      if (beresp.status != 200 && beresp.status != 404) {
          set beresp.ttl = 0s;
 @@ -128,4 +132,5 @@
      unset resp.http.X-Varnish;
      unset resp.http.Via;
      unset resp.http.Link;
 +    unset resp.http.X-Req-Host;
  }

In short this tell magento to pass the host name onto varnish they the user can choose to use this in the varnish config. In multi-domain sites it may cause more problems that it solves, but when running multiple sites on the same server one will not clear the cache of all others.

4 Comments
New Member
Status changed to: Investigating
 
New Member

Comment from choukalos, posted on GitHub Jun 03, 2016

We're tracking this improvement internally as MAGETWO-48944 . Would be great if you can send as a PR.

New Member

Comment from PieterCappelle, posted on GitHub Jun 04, 2016

+1

New Member

Comment from pynej, posted on GitHub Jun 06, 2016

Create RP: https://github.com/magento/magento2/pull/4905

Note that this may not seam like a necessary feature as in some setup's varnish can look at the invoked url. But in many cases the DNS might route externally so http_cache_hosts is used, or in cases with a shared caching serve or shared hosting. In these cases the address called in varnish in not the actual site domain so it needs to be passed as a header.

The only real issue I see with this, and the reason I only added the sample code to the vcl's and didn't turn it on is in multi-site setups the current behavior may be preferred. Ie if a single install is setup to run multiple storefronts on different domains that in that case the purge should clear all the storefronts.