Dapr Actors on Azure IoT Edge

Vitaliy Slepakov
3 min readJun 4, 2020

It’s been a while since my last post on Dapr with Azure IoT Edge so I thought it is a good time to create another one.

A long time ago in a galaxy far, far away, before Kubernetes became mainstream, I used Azure Service Fabric for quite some time on several projects. One of my favorite concepts there was the Actor model which allowed to achieve high degree of parallelism without the need to “manually” synchronize threads. Turns out, Dapr offers the same capability!

Here is an overview of how Dapr implements the Actor model, which is very similar (if not the same) as in Service Fabric. While Dapr currently targets Kubernetes, there are some scenarios on the Edge where Dapr Actor model might be advantageous. Here are a couple of examples off the top of my head:

  • Processing data from multiple devices/sensors in parallel
  • Implementation of the Identity Translation pattern (virtual representation of downstream devices with dedicated IoT Hub identities)
  • Creating an on-prem Digital Twin of your assets using an Actor graph

and there are of course more.

My sample implementation demonstrates the first scenario. Here is the high level structure:

Dapr Actors setup on IoT Edge

ActorClient simulates multiple sensors and passes generated sensor data to SensorActor instances by invoking an Actor method through the Daprd sidecar (which is started alongside the ActorClient inside the container). There are multiple ways to invoke Actor methods as a client: using Actor Service Remoting, without Actor Service Remoting or just using the REST API.

SensorActor is the actual Actor implementation. Dapr will automatically create an instance of this type for each unique ActorId (sensor in our case) basically providing a virtual representation of each simulated sensor. Sensor data is passed to the Actor implementation, again by the Daprd sidecar. Upon receiving sensor data, it is stored in Actor state (configured state store). SensorActor instances register a timer. When it fires, an aggregation is performed on all available sensor data for this particular Actor (sensor) instance and the result is sent to IoT Hub. This is done in parallel for all Actor instances.

Placement service is explained here. It is basically a cache of available Actor types and partitions (instances).

Redis is used as a state store for Actors.

As opposed to my experience with one of the previous Dapr versions, now there is no need to run containers on the docker host network so Daprd instances can discover each other. Using the environment variable DAPR_HOST_IP it is possible to specify the IP address or the hostname to be used. Now all IoT Edge modules run on the default azure-iot-edge network.

In order to configure Redis as a state store for Actors it is important to set the actorStateStore property to true.

When you run this sample it may happen that you’ll need to restart ActorClient and SensorActor modules if they come up before Redis and/or Placement modules. To make running it easier, I’ve included a generated deployment manifest which references pre-built container images from DockerHub.

Stay tuned for more Dapr awesomeness on Azure IoT Edge!

--

--