Structure of the example

Let's see how the streaming implementation changes the shape of our bakery app we've built Chapter 11An Introduction to the Akka and Actor Models, and Chapter 12, Building Reactive Applications with Akka Typed. To recap, this is the design of the bakery represented with actors:

Actors in this hierarchy had the following responsibilities:

  • The Manager initiated new baking rounds and performed the transfer of work packages between subordinates and supervised them.
  • The Boy was given a shopping list and acquired groceries from the remote system.
  • The Chef created and used a number of mixers of limited capacity in order to convert given groceries into dough.
  • The Cook formed a number of raw cookies from the given dough.
  • The Baker baked raw cookies in the Oven of fixed size. It maintained an internal queue of raw cookies in case the rest of the bakery was making them quicker than the Oven was able to bake them.
  • The Oven and Mixers represent hardware resources. They convert raw cookies into edible cookies and groceries into dough respectively but do so after some delay and with possible failures.

Now we have the possibility of defining relationships between participants in a more static way, so we will only keep initiating the behavior of the Manager and organize the work transfer at the flow level by connecting involved transformation steps directly together.

This is what the structure of our bakery will look like, represented in processing stages:

 

The hierarchical structure of the actor system has transformed into the flat data flow. Obviously, there are no Mixers and Oven anymore in this diagram. What happened to them? Well, we're cheating a bit by hiding the internal details of transformation steps here. In reality, some of these steps are composite blocks constructed from smaller components. Let's describe how it looks in detail.

The Manager only kept his initiating behavior. This will be represented by a timer source which will tick every now and then and push others to bake some cookies. The Boy can't work with just the Manager's desire so we need the Manager to give a proper shopping list to it. Thus we'll have to convert the ticking urge into the Shopping List as represented in the next diagram:

This composite block has exactly one output and no inputs and therefore it is clearly a Source[ShoppingList].

The real type of the source is Source[+Out, +Mat] as it is also taken into the account the materialization aspect. The materialization is non-essential for us for now so we'll talk about simplified pseudo-types as we describe the structure of the flow.

The Boy and the Cook are simple steps; both of them can be seen as a transformation of input into the output, and we'll look at the details of this transformation in a moment. From this description, we can conclude that the Boy is a Flow[ShoppingList, Groceries] and a Cook is just a Flow[Dough, RawCookies].

The Chef is clearly not as simple as his siblings. It needs to create a number of Mixer corresponding to the amount of groceries, use them in parallel to mix the dough, and combine the results together before sending them further. We'll represent this with the following structure: 

There is more going on in this diagram than we described before. This is because we combine the flow from building blocks with a single responsibility and we need to do transformations:

  1. We need to divide incoming groceries into portions suitable for a single mixer; this is the Divide step.
  2. Next, we need to be sure that work is evenly distributed among the mixers to avoid the situation where we need to wait for one of the mixers because it got multiple work packages. This is where Balance comes in play.
  3. The involvement of multiple mixers is obvious.
  4. The Merge step's responsibility is to be a fan-in block; it merges multiple streams of small portions of dough into a single stream of the same pieces.
  5. Finally we Combine small pieces into one big bowl before we give it further to process.

The kinds of internal sub-flows are as following the Divide, Combine and all of the Mixers are just Flows, the Balance is fan-out and the Merge is fan-in. The resulting type is the Flow[Groceries, Dough].

The Baker is also not as simple as it appears in the previous diagram because it hides an oven and the interactions with it:

The Oven in this diagram has one input and one output so this is just a Flow[RawCookies,ReadyCookies]. The Baker has two inputs and two outputs and its shape is a BidiFlow[RawCookies, RawCookies, ReadyCookies, ReadyCookies].

The resulting type of combination is Flow[RawCookies,ReadyCookies].

In the example built earlier, with an actor system the Baker maintained an internal queue of raw cookies as they arrived if the oven was not empty. This has a disadvantage that in the case of a really eager Manager the baking process could be initiated quite often and the raw cookies could arrive at the baker at much quicker pace than the oven can possibly bake them. The queue of the raw cookies can thus grow indefinitely large until it occupies all available space, and we'll need to either throw away raw cookies to free some space or close the bakery because there is no place for other actors to work.

In this version of the bakery we decided not to implement any queue but rely on the back pressure instead. We would expect the Oven to communicate with the Baker if it can't accept more work. The Baker will do the same, all the way back to the Manger, so that it won't be possible to even express the desire to have more cookies baked until there is more oven capacity available. With different buffering strategies, it is possible to manage how much work in progress there is at the bakery at any moment. For the purpose of the example, we'll set this limit low to demonstrate back pressure in action.

The last step of our flow is a Customer, which is of type Sink[ReadyCookies].

Now let's switch gears and set in the code the structure we came up with.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.14.245