Hacker News new | ask | show | jobs
by mjs 4984 days ago
This system ensures the server is always in a consistent state, but client race conditions are still possible if the "old" index.html references an asset that isn't available after the deployment has occurred. Is there any good way of dealing with this? (I just ignore it...)
4 comments

There is a simple way to solve the original problem and the one you mentioned. A load balancer. One that you have a good amount of control of and an API (such as Zeus, F5...)

You basically take the nodes off one at a time, wait for connections to finish, sync over code, then bring it back up. This does make some assumptions about assets -- that they are in a different location, such as a CDN or static server. If you are removing assets, you need to do this at the very end of this node-syncing process, so that any live "old nodes" aren't linking to deleted assets.

As for newly updated assets, you should be doing versioning for those anyway (even this 'symlink trick' fails when multiple application servers are involved and no shared code space).

Version your client assets. E.g. <img src="/img/v2.12.35/logo.gif" /> <link rel="stylesheet" type="text/css" href="/css/v2.12.35/frontpage.css" />

As someone mentioned before, hard-linking old and new deploy files means duplicated content doesn't cost any disk space. Rotate out old deploys past X days, and use strong cache controls to expire the content quickly.

In the past I've used <base> tags to "version" a deploy. The index.html was in the root directory and all other assets (including API endpoints, as it was a single-page app) were in a timestamped subdirectory, with a <base> tag pointing to that subdirectory.

It seemed to work well, but there are issues with <base> tags you should read up on first.

Two phases. Leave possibly referenced assets for a while until use of cached old files has become rare enough, then remove them.
Sure, but this approach is going to be much more complicated and less predictable than the "switch the docroot to a completely different directory" model. (e.g. you need to distinguish between asset and non-asset directories, and make a decision about how long to keep "old" assets around.) With some effort these problems can be solved, I'm just pointing out that even with a completely static site, and perfectly atomic docroot switching, you can still end up with clients in an inconsistent state.