Part I. Designing Next-Gen Event-Driven application powered by Stateful Functions

Tymur Yarosh
DevOops World … and the Universe
5 min readFeb 16, 2021

“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.”

― Antoine de Saint-Exupéry, Airman’s Odyssey

It is the first part of 3 parts saga, so take the kids to Grandma’s, grab a large thermos of coffee and be ready to get your hands dirty with some code. This article is not an ultimate guide to Stateful Functions nor a replacement of the official documentation. For a deeper understanding of the generic concepts, I encourage you to read through the official resources. This part aims to teach you the basics of modeling a Stateful Functions application through an example.

A brief introduction to Stateful Functions

The most crucial principle of the whole engineering discipline is KISS, the acronym that came from military engineering in 1960. It states that the most simple systems are the most reliable ones. However, the software we build nowadays is exceptionally complex, especially distributed event-driven applications: complicated choreographies, distributed transactions, tradeoffs between message delivery semantics, data consistency models, and so on. Though Event-Driven Architecture isn’t something new and exists for decades, software engineers still face these issues daily.

Stateful Functions is an API that turns Apache Flink into a platform for running event-driven applications and dramatically reduces developers’ headaches. The API provides four major types of components:

  • Stateful Function — Stateful event producer and consumer
  • Ingress — Input port of the application
  • Ingress router — Component that routes ingested events to functions
  • Egress — Output port of the application

The general flow is the following:

  1. Ingress ingests incoming events into the application.
  2. Ingress Router delivers an event to a particular Function.
  3. The Function consumes an event and can produce another one.
  4. The Function sends an event to the Egress.
  5. Egress delivers the message to a message broker.

Applications implemented in line with this simple approach are easy to understand and extremely flexible. To better understand these components let’s locate them in Uncle Bob’s Clean Architecture:

Enterprise Business Rules — Domain models that Stateful Functions interact with

Application Business Rules — Stateful Functions

Interface Adapters — Ingresses, Egresses

Frameworks & Drivers — Everything that connects Ingresses and Egresses to the outer world

Stateful Functions can implement both Enterprise Business Rules and Application Business Rules in applications with thin business layer to avoid over-engineering.

The focus of this part is the design of the core of Stateful Functions application — functions:

The showcase

To show you the simplicity you can achieve with Stateful Functions, we’ll build a product that the Israeli government launched in 2020 to stop the coronavirus epidemic. The idea was to notify citizens who might be infected if they had contacted sick people. There are a few ways to implement this behavior, so we chose the one that better showcases Stateful Functions’ abilities.

Let’s divide Earth’s surface into millions of small sectors:

..or to just four sectors for the sake of brevity.

Hey, look! There is Alice! She’s at home now, talking via Zoom with her teammates. Her smartphone frequently sends GPS coordinates to the Location Preprocessing Service:

The Location Preprocessing Service maps incoming GPS coordinates into sectors they belong to. The next stop is the Stateful Functions application we’re going to build:

The typical pattern for apps with a thin business layer is implementing Enterprise Business Rules as Stateful Functions. We need two functions here: FnSector and FnPerson. Ingress Router sends the event to the FnPerson function instance with the id Alice. After the function instance receives an event with the new sector, it sends SectorEnteredEvent to the FnSector function.

While we were discussing the events, Bob entered the yellow sector, and Joe joined the green one:

Then Alice finished her Zoom conference and moved to the green sector:

The following happened here:

  1. FnPerson (Alice) received a green sector event and sent SectorQuitEvent to the FnSector function responsible for the blue sector.
  2. FnPerson (Alice) sent SectorEnteredEvent to the FnSector function responsible for green sector.
  3. FnSector, responsible for the green sector, figured out that both Alice and Joe are in the green sector, so it sent PathsCrossedEvent to Alice.
  4. And then to Joe.

Both FnPerson instances of Joe and Alice know that humans crossed the paths. And the last movement for our example — Joe noticed Bob and moved to the yellow sector to say “Hi!”

So Alice met Joe and Joe met Bob. Alas, Joe got sick and was diagnosed with coronavirus. The government registered the diagnose and sent a new event to our engine — DiseaseDiagnosedEvent:

After (1) the event routed to the FnPerson (Joe), the function:

  1. Sent PersonInfectedEvent to FnPerson (Alice).
  2. And to FnPerson (Bob) as well.

Both FnPerson instances figured out that Bob and Alice might be infected as well since they were in contact with Joe. So, (4, 5) each function instance emitted PersonMightBeInfectedEvent. These events can be forwarded to the Notification Service and then to the SMS Gateway so that both Bob and Alice could receive a text message, get tested, and self isolate before they infect other people.

Cliffhanger

Stateful Functions is an API that provides four components for distributed Event-Driven applications: Ingress, Ingress Router, Egress, and Stateful Function. In our case, Stateful Function components implement both application business rules and enterprise business rules, though feature-rich applications should limit them to implement application business rules only.

Therefore, are you ready to stop the most annoying disease of 2020 with the combination of this fantastic piece of technology and your engineering talent? If so, let the hacking begin!

In the next part, we’ll take a closer look at the Java SDK and implement the whole application.

--

--