Azure IoT SDKs for Node.js v1.2.0 (Device) and v1.1.18 (Service)
New Feature: Device SDK automatic and custom retries
A large proportion of issues reported with the device SDK are connectivity issues. with this in mind we set out a few months ago to rewrite the transports layers to be more stable and introduced code that enabled better state and error management for each protocol - in this release, we were finally able to remove the over-arching client state machine that had become useless and was causing issues. We have now introduced per-operation retries on top of that.
This means that when a user calls any of the device client API (subscribe to receive C2D messages, send telemetry, etc) the client doesn't have to know what the transport should do: just ask the transport to do it and report. the transport can then bubble up either a success result or an error. It's then up to the client to ask the transport to retry or send the error back to the user.
By default, the client will retry using "an exponential backoff with jitter" strategy, for up to 4 minutes. This is done without any changes to the API surface. your code will automatically benefit from this.
It is possible for a user to disable retries alltogether, or to define a custom retry logic and feed this to the client using the Client.setRetryPolicy()
API.
For example:
var Client = require('azure-iot-device').Client;
var Amqp = require('azure-iot-device').Amqp;
var NoRetry = require('azure-iot-common').NoRetry;
var client = Client.fromConnectionString('<connectionString>', Amqp);
// Disable Retries
client.setRetryPolicy(new NoRetry());
// Custom retry policy
var myRetryPolicy = {
shouldRetry: function (err) {
// decide depending on err if you would like to retry or not - should return true or false.
},
nextRetryTimeout: function (retryCount, throttled) {
// should return an integer that is the number of milliseconds to wait before the next retry
// based on the current count of retries (retryCount)
// and if the IoT Hub is asking clients to throttle their calls (throttled, boolean)
}
}
client.setRetryPolicy(myRetryPolicy);
caveat
There are a few issues that this won't solve and that we will tackle next:
- There are a few errors coming from the MQTT library that we are not catching because they are thrown before we can attach an event handler on the
error
event - we are looking for ways to circumvent this - The Twin feature requires heavy refactoring to support a fully-fledged retry logic - right now twin operations are not being retried automatically.