We have a Flash-based application that uses lots of different SWF files, along with numerous HTML, Javascript, PHP, XML, and image files. The server is running NGINX 1.13.3. (We've got an HTML5/JS replacement in development, I think the issues here apply just as well to it.)
The file organization under our webroot is like:
/client/client.php
/client/client_v48
app.php
MainLine.swf
other files and subdirectories
/client/current_client symlink to client_v48
The way thing currently work is this:
client.php
sends a redirect to current_client/app.php?cb=<randomstring>
. app.php
returns the HTML for the main page of the application, which includes the <object>
tag that loads MainLine.swf
, and it then loads all the other resources it needs. Throughout the application, everything uses relative URLs, we don't hardcode v48
anywhere.
So now we want to release v49 of the application. We create a /client/client_v49
directory, deploy all the files to that directory, and change the symlink. But many browsers still have old versions of the files cached. The cachebuster on the redirect ensures that they get the latest version of app.php
, but there's no cachebuster on all the other URLs used throughout the application. All the URLs are /client/current_client/...
, they don't change from one version to the next.
How can we ensure that when we release a new version, clients pick up the latest version of everything. We can send Cache-Control
headers, but that doesn't seem to be good enough. Different files in cache can expire at different times, so clients may end up with a mix of files from different versions.
In the past we solved this by putting the client inside an iframe. client.php
contained something like:
<iframe src="client_v48/app.php"><iframe>
When we released a new version, we changed the version number in the iframe source. Users didn't see the version number in the browser location, so they didn't inadvertently bookmark it. But some of our ad providers don't allow embedding inside iframes, so we had to get rid of this.
That's when we switched to using a redirect through the current_client
symlink, and encountered the caching problem.
What we've been doing since then is giving a different name to the current_client
symlink. So when we release v49, we create a new link:
/client/curclient => client_v49
and change client.php
to redirect to curclient/app.php
. This seems very unclean, there has to be a better way. Also, more than 4 months since our last update, we still see a small number of hits on the previous symlink, suggesting that some users bookmarked it, so even this isn't a perfect solution.
How do other sites ensure that all the cached files stay in sync when deploying new versions? Do we just send a really short Max-Age
for everything, to keep the window very small?