Intelligent roads and vehicles of the future will rely on a highly distributed, event- and data-driven IoT architecture that will have to provide local, inter-platform, and cloud-based services. Processing and integrating high volumes of geographically distributed raw data will become a frequent task in the intelligent automotive and transportation domain, and due to throughput and latency constraints, there often will be no other viable choice but to localize processing power – which is also the main driving force behind the emergence of edge cloud technology and the underlying system and software architectures and best practices. Automotive edge cloud services are envisioned to be reliably responsive despite their scale, distribution, and interdependence. The Reactive Manifesto  stipulates that responsiveness of massive event-driven systems is achieved via design practices that also facilitate elastic scaling and resilience to failure. The underlying technological cornerstone of such practices is asynchronous messaging; thus, a programming and software design approach that abstracts and transparently supports distributed processing of asynchronous dataflows is becoming increasingly indispensable.
The so-called actor model is a physics-inspired, mathematically grounded, mature process calculus and programming paradigm for distributed, asynchronous, and concurrent computation . The actor model is rapidly gaining importance with the emergence and soon ubiquitous prevalence of various IoT and edge computing environments, including the automotive one, although it has been in use for designing telecommunication and networking software for decades. It defines an actor as a universal processing primitive that has an identity and a corresponding entirely encapsulated, private state. The only way to affect that state is via asynchronous and sequential consumption of messages (which themselves are immutable structures). In reaction to receiving a message, an actor can
• change its internal state; and/or based on its state
• send messages to other actors (in parallel); and/or
• instantiate new actors.
Since actors are entirely isolated via messaging, the well-known high-cost problems associated with concurrent access and its synchronization are thus eliminated. This approach is both similar and different to classic functional programming as it achieves the same level of inherent concurrency support but relies on messaging instead of immutability and is thus more suited to the data-driven environment.
At this point an alternative paradigm must be mentioned: functional reactive programming (FRP) [4,5] extends the original idea of pure functions by mapping input event-streams to output event-streams while retaining full immutability. Note that statelessness is understood on the stream level: the same individual event may map differently depending on its place in the stream. This corresponds to the stateful behavior of the actor model. A major difference between FRP and the actor model is that while the former assumes an ordered and timelined sequence of events, the latter makes no such assumption and processes messages in their ad-hoc arrival order. FRP thus gains some advantages like idempotence of compositions, but it also constrains the signal source to a single system that can provide consistent event message arrival ordering (e.g. a GUI). In contrast, the actor model does not have this kind of restriction, but it also loses the related benefits. Since our practical use cases often involve data integration from various sources compacted with network delays, the actor model is the paradigm that we are detailing in this post.
A further important feature of the actor model is its inherent assumption of asynchronicity between loosely coupled actors, which is well suited to the heterogenous and highly distributed nature of the transportation environment. Failures of networks or any subsystems will not endanger transactional semantics (e.g. exactly-once message delivery) – such guarantees of eventual consistency can always be ensured at the cost of performance, if so desired. Beyond the messaging resilience, the possibility of instantiating new actors on demand creates an actor hierarchy that allows for further failover logic. It also facilitates scalability, and thus perfectly fits the requirements of reactive distributed systems. Regarding the loss in semantic consistency due to the lack of control in message ordering, retroactive event ordering and aggregation can be realized with some effort, using synchronized timestamps and buffering – enough to serve most practical purposes.
Altogether, we found the actor model a suitable starting point and a much-used template in our system designs on several levels. We make use of the akka  concurrency framework on the intra-process level, while inter-process computational graphs are powered by the Kafka  event streaming middleware platform. Akka is an implementation of the actor model on the JVM that uses message queuing between actors and integrates well with gRPC and Kafka, while Kafka itself is a more general, topic-oriented (consumer-agnostic) message log broker which can be used as the underlying transport for a distributed actor model. Despite some differences, both frameworks offer high-performance stream processing in terms of throughput and latency, and both frameworks support the development of highly available, distributed, scalable, fault tolerant and redundant systems.
 Hewitt, Carl, Peter Bishop, and Richard Steiger. "A universal modular actor formalism for artificial intelligence." In Proceedings of the 3rd international joint conference on Artificial intelligence, pp. 235-245. 1973.
 Elliott, Conal, and Paul Hudak. "Functional reactive animation." In Proceedings of the second ACM SIGPLAN international conference on Functional programming, pp. 263-273. 1997.
 Nilsson, Henrik, Antony Courtney, and John Peterson. "Functional reactive programming, continued." In Proceedings of the 2002 ACM SIGPLAN workshop on Haskell, pp. 51-64. 2002.
Written by Software Platform Team