Distributed locking in Azure Functions

Francisco Beltrao
2 min readJan 7, 2019

--

Imagine a scenario where IoT devices send telemetry data to Azure IoT Hub containing measured temperature. Based on the temperature value a notification should be sent. What if you want to limit the notifications sent by each device to once every minute? Keep reading and I will show a possible implementation.

Solution demonstrated here

As to most software engineering problems there are multiple solutions to a problem. The one demonstrated here uses Azure Functions to process telemetry data coming from IoT Hub, sending a notification if a device temperature gets too high.

The challenge is to ensure that a single device will not trigger the alert more than once every 60 seconds. The approach demonstrated in the repository uses distributed locking backed by Azure Storage or Cosmos DB.

Locking using Azure Storage

Azure storage locking implementation relies in leasing blob files for a certain amount of time. Once a blob is leased, no one else can lease it until it the expiration time is reached. Leasing in Azure storage must stay between the range of 15 to 60 seconds.

The implementation is the following:

Locking with CosmosDB

Locking with CosmosDB relies in having a document structure that identifies until when a document is leased.

{
"id": "deviceID",
"leaseID": "<instance-id-that-adquired-the-lease>",
"leasedUntil": "<time-when-lease-will-expire>"
}

Updating the lease relies on the document etag to ensure that a single updater will succeed. Unlike the Azure Storage implementation, CosmosDB does not have any limits regarding the locking time.

The code looks like this:

The sample project found in the repository contains an IoT Hub and Http Trigger implementation that uses ThrottledGate to limit the amount of notifications per device generated. Moreover, it has a InMemoryThrottleGate implementation that caches leases in memory with the goal of reducing calls to the backend implementation (Storage or CosmosDB). The optimisation usefulness depends on the scenario and how often a device triggers an alert (before adopting measure in your use case).

Creating a storage based throttled gate:

Using it:

Extending throttle gates with different backend services

Adding new providers is simple and can be implemented according with backend service you are familiar with (SQL databases, Redis, etc). Take a look at the ThrottledGate abstract class to understand the implementation requirements.

--

--