The flow of immutable messages with Akka.Net

Alexandre Brandão Lustosa
4 min readMay 2, 2019

--

Hi DotNerds friends, follows another article, the sequence on Akka.Net with a practical approach. Now in this article, I’m bringing a very interesting feature, the message flow control by type, where I define an actor that will function as the message gateway.

Understanding the model

It is not a standard approach, since, ideally, each actor is a simple business unit, so there is a vertical scale in distributed and/or multithreaded processing in a single core. However, it is an interesting flow control model that the Akka.Net library allows. I often use it with a certain frequency when I have chains of decisions with very close purposes. For example, in an online payment processing scenario where there is the main actor (gateway) that depending on the type of message chooses the means of payment to be processed.

Activity Diagram

In this model always use the asynchronous call Tel () and never the Ask (), to not generate dependency of processing in its pipeline of actors.

To better understand the application of this technique and the processing flow of the gateway actor, the message diagram among the actors of the system follows.

Message Flow Sequence Diagram

Structure

This example is structured as follows:

Folders:

Actors: Contains the ActorReport class.
Domain: Contains the Company and Person domain classes.
Library: report print class.

Program.cs file

View the Program.cs file on the left, and the right the folder structure of the application. The Sample Code for this application is available from GitHub at the link:

Analyzing the code

Let’s get right to the point, domain classes must be immutable, so their attributes are given the private modifier and values ​​are injected via constructor.

The following is the code for the Domain class Company that will be transported as an immutable message:

Domain class Company that represents an immutable message.

Here is the code for the Person domain class, which will be transported as an immutable message:

A domain that represents an immutable message.

We already have the domain defined, now we go to the code of the actor. The actor defined for this example has the function of generating different reports, according to the received domain, acting as a gateway, that is, in a professional code, when the Receive <T> method is called, it must process the business rule, call additional classes and libraries, or even forward the message to an upcoming actor, such as in a streaming pipeline with actors.

In our example, to be didactic, depending on the type of message received the actor makes the impression differently on the screen. If it is of the Person type, the class is serialized in json format and then the data is printed on the screen, however, if the immutable message received is of type Company, the second Receive <T> method is invoked, the call to a report printing method.

ReportActor class responsible for the processing and decision making of the immutable message flow

The print logic of the report can be seen in the RepostCompanyProcess class that is contained in the Library folder.

ReportCompanyProcess class responsible for printing the data on the screen

The SendReport method receives an object of type Company, immutable message, and prints to the screen as formatted above.

In the main code, in the main method, the actor system is created and an instance of the ReportActor actor is created. Then, with the Tell() asynchronous method, the messages are sent to the inbox of the actor for processing.

Main program code

This is the output print after the program is run. Note that the same Tell() method is used for so-called immutable messages, with different goals. Therefore, we observe an interesting behavior for the decision making process flows, and all the call made to an actor is executed in a separate thread, if the messages are immutable and multiple instances of actors are created, so we have the behavior of Multithread without having to worry about Shared Memory.

This is a simple way of making decisions by type, using Akka.net, where its most interesting application is in assembling calls, sequences of actors as processing pipeline.

--

--

Alexandre Brandão Lustosa

Microsoft MVP, Senior Software Engineer with 25 years of experience in web development, transactional and distributed systems, Microsoft C# .Net, MSSQL MCSA