Akka Process Framework
Akka is a great framework when you want to write reactive applications. While writing applications with Akka I noticed
that it was somewhat difficult to write processes flows. In this blog post I will show why it is not trivial to write a
process with Akka and how the ProcessFramework (https://github.com/jgordijn/process) solves this.
Let’s start by writing a rather simple process for order processing. We do not allow orders to be lost. This means
process needs to be persistent. The application can restart the process after application restart (or rebalancing).
The flow is like this:
Let’s try to implement this in plain Akka with AkkaPersistence. A process starts with some command (in our case this is the incoming order). We need to keep track of the progression of the process. Therefore every step which is performed should be persisted. When the process is restarted, all events should be replayed and the process should continue where it left before the restart. Fortunately
AtLeastoncedelivery can help us with that. During recovery all messages are queued until all events are replayed. A pending message can be removed from the queue during recovery (read more at: Akka documentation). When recovery is finished any pending message will be send. While this mechanism is great, the consequence is that logic is moving to the
updateState. From an evount-sourcing perspective, this is not desirable.
As you can see it is quit hard to see the releation between the drawed process and the code. This makes code hard to maintain and bugs are harder to spot.
The process framework is aimed at getting the process image and code more in sync. Ultimately allowing non-technical people to look at the code and understand the process flow.
A process consists of two pieces:
- Steps which perform actions and have side effect
- The process flow definition which combines the individual steps into a flow.
Let’s look at how the flow in the picture above would look like when written with the ProcessFramework. We need to create instances of the steps which can be used in the process definition. Looking at
def process we can correlate the image of the process above with the code below. You can clearly see what the process flow is.
The flow is now clearly defined, but we still need to implement the action that needs to be taken by steps. Let’s implement the EmailStep. A step follows the rules of event-sourcing, so performing the action and updating state is separated into different parts. A step has three functions you need to implement:
executefunction executes the logic of the step and can use the state to do so.
receiveCommandreceives events back from other actors as a result from the
execute. This is the place to define the
Eventthat needs to be stored.
updateStateupdates the state with the
Eventthat was emitted by step 2. The changed state is stored in the process, so that it can be used in following steps.
The ProcessFramework is aimed at making it easier to implement business processes with Akka. I’m very proud of the result and I think that the goal is achieved to make the process flow readable. It is currently used in production, so it is proven to work correctly. The intention is to add more functionality to it, so that it becomes more and more complete.
I am very interested in your opinion and invite you to leave a comment.