Skip to main content

Polite Squirrel Deployment

How to ensure that Squirrel code updates don’t interrupt busy devices

Polite deployment is the process by which a device and its agent, having been notified by the Electric Imp impCloud™ that an application or impOS™ update is available, can elect to delay the installation of that update rather than receive and apply it immediately. This allows critical tasks to be completed without interruption.

This document will focus on polite Squirrel deployments; please see the documentation here for assistance implementing polite impOS deployments.

How to Make Use of Polite Squirrel Deployment in Applications

Polite deployment makes use of two imp API calls: server.onshutdown() and server.restart().

The first of these methods registers a function which will be called when the impCloud asks the device to reload its application code. Without polite deployment, the reload request is actioned immediately: impOS shuts down and restarts the Squirrel virtual machine; this causes the device to enter the ‘Get Squirrel #2’ state shown in the Network State Diagram and acquire the new application code (or time out).

If a shutdown handler function has been registered, however, this update process is bypassed: the shutdown handler is called instead, and the application continues to run.

The shutdown handler is registered by calling server.onshutdown(). The handler function passed into this imp API method takes a single parameter, reason, into which an integer constant is passed to inform your code why the restart has been requested. These are the possible values of reason:

  • SHUTDOWN_NEWSQUIRREL — New Squirrel is available
  • SHUTDOWN_NEWFIRMWARE — New impOS firmware is available
  • SHUTDOWN_OTHER — A restart has been requested for some other reason*

*SHUTDOWN_OTHER is not currently used but is reserved for future usage.

Until server.onshutdown() is called, impOS will respond to any request from the impCloud to reload its Squirrel by initiating the upgrade process. As such, it is essential to call server.onshutdown() as early as possible in your application code.

Once the application is ready to be upgraded, it should call the second imp API method, server.restart(). This causes impOS to follow its usual Squirrel reload procedure: restart the Squirrel VM, and acquire and run the new application code.

Note Polite deployment is managed entirely through Squirrel, so there may be instances when Squirrel updates are applied even when polite deployment support is in place. For example, if a device is power-cycled, it may update its Squirrel code before Squirrel starts. Until Squirrel is running, any handler registered with server.onshutdown() cannot be executed. In short, polite deployment is only available when Squirrel is running.

In addition, if a device is moved from one Device Group to another, that will also operate as a forced deployment.

It is strongly recommended that you code your application to avoid restarting at a specific time, to prevent all of your devices attempting to contact your server and/or other web resources simultaneously on restart. Typically, they should restart after a short time, or at a random time within a broad interval. For example, you might code your devices to restart between midnight and 5AM device local time, with a given device’s restart time a random point within those bounds.

Controlling Polite Squirrel Deployment Via impCentral

The polite deployment process is not mandatory: it is only effective if the application is written to take advantage of it, by calling server.onshutdown(). Even if you have employed polite Squirrel deployment, you can choose to override it and force the update to be installed immediately.

This choice is made in impCentral™: when you deploy code to a Device Group, you can opt to choose a forced or a conditional deployment.

For example, in impCentral’s code editor, these options are provided via the Build and Force Restart menu:

impCentral code editor restart options

Let’s say you have updated the device code listed in the code editor. If you now click on the menu triangle and then click Build and Conditional Restart, your installed application code’s server.onshutdown()-registered function will be called, and the device itself will then determine whether it should update now or later, when a critical task has completed.

Bear in mind that if you have not added deployment management code to the versions of the application the device is running when you click Build and Conditional Restart, then performing a conditional deployment will be equivalent to performing a forced deployment: the device will restart and reload the new code immediately.

A forced deployment will take place if you click Build and Force Restart — even if the code running on the device has polite deployment support.

The Build option will always stage the deployed code without triggering a restart: devices must be restarted manually to receive the deployed code.

Current and Minimum Deployments

impCentral gives you further control over conditional deployment by allowing you to specify deployment ‘versions’: Current and Minimum. The Current deployment is always the most recent deployment made to a Device Group, whether devices have it installed or not. The Minimum deployment marks the level at which devices within a Device Group will undergo a forced upgrade — even if they have a shutdown handler registered.

How does this work in practice? Devices in a Device Group which are already running Current will not trigger the application code’s server.onshutdown()-registered function when they are asked to restart — they will simply restart (there is no new application code).

Devices that are running a deployment that pre-dates Current but was deployed later than Minimum, or are running Minimum itself, will trigger the application code’s server.onshutdown()-registered function if they are asked to restart. When their installed application code subsequently calls server.restart() they will receive new Squirrel: the Current deployment. Note that if you mark the Current deployment as Minimum too, all your devices will receive Current when they restart.

Devices that are running a deployment that pre-dates Minimum will not trigger the application code’s server.onshutdown()-registered function if they are asked to restart — they will simply receive new Squirrel: the current deployment.

For restarting devices whose application code makes use of polite deployment:

Deployment Currently Run by a Device impCentral Conditional Deployment/Restart impCentral Forced Deployment/Restart
Deployment > Current Device restarts
server.onshutdown() called
New application code installed
Deployment becomes Current
Device restarts
server.onshutdown() not called
New application code installed
Deployment becomes Current
Deployment == Current Device does not restart
server.onshutdown() not called
No new application code installed
Minimum <= Deployment < Current Device restarts
server.onshutdown() called
New application code installed (Current)
Device restarts
server.onshutdown() not called
New application code installed (Current)
Deployment < Minimum Device restarts
server.onshutdown() not called
New application code installed (Current)

For restarting devices whose application code does not make use of polite deployment:

Deployment Currently Run by a Device impCentral Conditional Deployment/Restart impCentral Forced Deployment/Restart
Deployment > Current Device restarts
New application code installed
Deployment becomes Current
Deployment == Current Device does not restart
No new application code installed
Minimum <= Deployment < Current Device restarts
New application code installed (Current)
Deployment < Minimum

Minimum and Current are initially the first deployment made to a Device Group. As further deployments are made, Current will always be the most recent deployment, but Minimum will not change until more than ten deployments have been made. From that point, Minimum always stays ten deployments behind Current, unless you use impCentral to adjust it upwards. Minimum can never be adjusted downwards. If you move Minimum up, afterwards, as new deployments are made, it will again remain unchanged until Current is ten deployments ahead, after which Minimum will always be ten deployments behind Current.

For example, when you make the eleventh deployment to a Device Group, Current is deployment 12, and Minimum automatically becomes deployment 2. When a further deployment is made, Current becomes that deployment (13) and Minimum becomes 3, ie. ten behind Current. I now re-set Minimum to 8. Current will have to reach deployment 19 before Minimum again moves up automatically, to deployment 9.

For Production and Factory Device Groups, the choice of deployment type is made when you deploy code to them by clicking Deploy under the MANAGE column in their respective Production Zone lists. In the Deploy panel, select either Forced Restart or Conditional Restart as required:

Production Device Group Restarts

Again, if your application code doesn’t support polite deployment, all restarts are de facto forced. And forced deployments will always override an application’s own polite deployment support. In addition, if a device is moved from one Device Group to another, that will also operate as a forced deployment.