Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent bundle from responding if cache buster doesn't match content

I'm using Bundling and Minification across a server farm where there is a cross-over period of old and new servers.

The issue I have is that the old servers are caching the content of the new bundle cache buster URL.


For example the new HTML is cached with the new bundle URL:

<script src="/bundle.css?v=RBgbF6A6cUEuJSPaiaHhywGqT7eH1aP8JvAYFgKh"></script>

This then makes a request to an old server which hasn't yet been updated with the new CSS code and this then cached.

Any subsequent calls to the new bundle URL will then return the old code.


Therefore is there a way of checking that the content of the bundle matches the hashed cache buster? And if it doesn't throw a 404 for example.

Using my example above when the request goes back to the old server for the bundle it would check the contents of the bundle, generate a content hash and compare this to the querystring.

In this instance the cache-buster wouldn't match the actual content hash and a 404 would be returned.

Eventually a user would hit a new server with the bundle request and the correct content would be cached.


enter image description here

like image 814
Curtis Avatar asked Jul 21 '15 09:07

Curtis


1 Answers

We're bound to encounter the same issue ourselves soon, but we've been sticking to only 2 update domains (split the servers in half so that there's not more than one version running at a time).

As far as I see it there are 4 possible alternatives:

  1. Have your static content always point to an up to date server. This could be done (depending on your configuration) by IP address or by using a URL that you know has already been updated (if you have a server that gets updated first).
  2. Configure your load balancer so that requests from the same IP address end up on the same system (if your static content is served from your app servers). If this can't be done at the load balancer level then you can do it further up by configuring different IP addresses for different environments and then swapping their DNS records around.
  3. Implement a handler in ASP.NET that listens for CSS files, and checks whether the hash of the bundle is what it expected to be. You will probably need a singleton object to be storing these when they're generated when your app loads. This can then either return a 404, 301 (to get them to retry) or return the old version but instruct it to not cache the results. Note that with HttpPipelining you're not likely to hit a different server so a redirect might not help.
  4. Have a config flag that is set while you're doing a deploy that changes all of your cache-busting URLs to be the current date. This will effectively disable all caching until your deploy is completed, meaning that any "wrong" assets delivered will not be kept.

Is this a problem you're actually seeing, or is it hypothetical? Unless your site is very high traffic and your deploys take a good few minutes it's not something you're likely to see. You'll want to be wary of returning 404s as sometimes the wrong stylesheet is better than no stylesheet.

like image 121
Matthew Steeples Avatar answered Oct 14 '22 00:10

Matthew Steeples