Introducing Update Strategies and zero-downtime updates
At resin.io, we want to give you full control over your devices while keeping the experience as simple as possible. Going with this philosophy, we have recently released a new feature, Update Strategies, to give you more power over how your application gets updated on the device.
These strategies control the order in which your containers are killed, downloaded and started, and there's three of them:
The strategy is selected using an environment variable (
RESIN_SUPERVISOR_UPDATE_STRATEGY) using the resin dashboard, CLI or SDK.
The default behavior (which corresponds to how resin has been working so far) is 'download-then-kill', that is, we download the new image onto the device, then kill the old container, then start the new one.
The next strategy, 'kill-then-download', is useful for memory-constrained devices. It kills the old container before starting the download for the new one. This gives a longer downtime, but frees up memory to prevent out-of-memory situations that may happen if you're downloading a large image.
Last but definitely not least, the 'hand-over' strategy allows you to implement a zero-downtime update. It first downloads the new image, and starts it alongside the old container. Your application should, in this case, allow communication (with a local API endpoint, for instance) between the old and new container. The new container should notify the old one so that the old version can shut down, free resources, or do whatever it needs to do so that the new version can start controlling the device. After that, the app should create a file at
/data/resin-kill-me so that the Resin Supervisor knows that it can kill the old version. There's also a timeout for this, that defaults to 1 minute and can be controlled with the
RESIN_SUPERVISOR_HANDOVER_TIMEOUT environment variable, setting a value in milliseconds.
Here's a technical diagram illustrating the three methods of updating a resin.io application:
You can find the full documentation for this feature in our docs.
Choosing between these three strategies should allow you to adapt the way resin works to your particular application, device and needs (am I the only one thinking about updating a drone in mid-air?). We hope they'll prove useful to our users, and we can't wait to hear what you'll build with this. Any ideas? Are there other update strategies that would be useful to your use-case? Drop us a line or chat to us on Gitter and we'll be happy to talk about it. And if you're curious about how we implemented this, take a look at the source code.