Digital Twins - Utilizing Virtual Actors through Dapr
As stated before, "A Digital Twin is a virtual representation of a physical object". This virtual representation should strive towards being an exact copy of the physical object in both state and logic associated with it.
Note: this is a continuation on my previous posts around Digital Twins and a RL Digital Twin Platform, I recommend you to read these first to get the most out of this post.
Because this physical object has a state and logic connected to it, it's therefor interesting to take a look at the Actor Model. But before going any deeper, let's brush up our knowledge of the Actor Model.
The Actor Model
A good introduction and summary is given by Service Fabric, which states that: "an actor is an isolated, independent unit of compute and state with single-threaded execution. The actor pattern is a computational model for concurrent or distributed systems in which a large number of these actors can execute simultaneously and independently of each other. Actors can communicate with each other and they can create more actors".
With as one of the biggest benefits of using actors being that when we are hosting these actors on different hosts (a cluster). We have an actor framework behind it that manages these. This means that in the event of a host failing, that it will automatically trigger a failover to another node.
Another advantage of the actor model is that these actors can be small, allowing us to host thousands of actors on the same host.
Examples of Actor implementations:
I have chosen for the Dapr framework (seeing it's excellent compatibility due to its Kubernetes foundation). To quickly illustrate the working of Dapr its Actor implementation we can take a look at the following diagram:
Here we can see that the application will access the Dapr framework as it normally does (e.g. through its REST or gRPC endpoint), which in its turn will utilize a Placement Service to determine which actor to send our request to.
Note: Mark Russinovich explains the Dapr Actor Model in more detail here and here.
Example 1
To put this into something we can grasp more easily, think of an actor as an instance of a class that you created. An example here could be a Vehicle class
, where the vehicle can have a type
(e.g. car, bus, bike, …) and the numberOfWheels
(4, 2, …). We can then take actions on this vehicle such as ride()
.
Example 2
As demonstrated by Mark Russinovich, an Actor could for example be a Virtual Game Enemy, where this enemy has properties ({X, Y, Z} position
, Difficulty
, Weapons
) and actions (Spawn()
, Attack()
, …)
Actor Model in Digital Twins
Mapping the explanation of the Actor Model above to our Digital Twins concept, we can find a perfect fit. Since Digital Twins are a hierarchical representation of sensors, it are the sensors that can be represented as actors (after all, a sensor has a state (e.g. temperature) and logic (e.g. readTemperature()
).
Creating an architecture from this, we could illustrate the above as an Telemetry Hub (e.g. IoTHub) which is receiving telemetry that get mapped to different Actors. This mapping can happen by an inbetween "routing" microservice, which is sending the telemetry to the correct actor. In case of Dapr, this would translate in converting the IoT Hub message to an actor update method (but more about this later).
Once data is being ingested into our actors, we can then apply a Digital Twin hierarchical model on top of this (which can be stored in a metastore), that can be queried through an API microservice behind it.
The biggest advantage here of such an architecture is that it is able to scale to the sensors in use. No matter if we have 1.000 sensors or 1.000.000 sensors, due to the use of an actor, the underlying infrastructure can scale and distribute the actors over the different nodes (which is handled by Dapr).
Putting the above into an architecture diagram results in the following:
Conclusion
In this blog post I explained how Digital Twins could be implemented through the Actor Model. Of course as with any theoretical explanation, there should also be a technical implementation. So stay tuned for a next blog post where I will explain how we can implement this with Dapr.