jjmargon (11) [Avatar] Offline

I'm really interested about this topic, as it's supposed to cover how a reactive application can deal with business processes in a consistent manner.

The question arises from the code sample in the classical use case of a bank transfer between 2 accounts:

- a first message would go to "fromAccount" actor to withdraw the money. Let's imagine this actor can do its work and answers back with an Acknowledgement message.
- then, a second message would go to the "toAccount" actor to deposit the money. Let's imagine this account actor cannot do its job and we don't receive the Ack message. Then, a TransferFailed message would be sent to the client.

But, with this last message, the client only knows that something went wrong, but not what was wrong. But even if the client could know what was wrong, the responsability to keep both accounts in a consistent manner (i.e., in this case, give back the money to the "fromAccount") would be in the client actor, what seems quite strange. Wouldn't that responsability be in the process manager itself?

And this is only a very brief and simple use case. Most real business processes involve a lot of domain contexts (boundaries) that should remain in a context manner.

In the non-reactive world, this can be easily managed by a mix of the classical RDBMS transactions and BPM engines (as Activity, for example).

Currently, with the content I've learned, I cannot see a consistent model of business processes in the reactive world through these kind of "Process managers". I might miss something, of course, as I'm a newbie about reactive.

Thanks a lot and congrats for the work on the book.
bhanafee (14) [Avatar] Offline
>In the non-reactive world, this can be easily managed by a mix of the classical RDBMS transactions and BPM engines

The client in this situation occupies the same place in the architecture as a process manager or a BPM activity. That actor can indeed (and often would) be given responsibility for recovering or reconciling the transaction. It's the only part of the system that knows about both parts.

Chapter 6 shows you some of the primitive operations that are used to manage system reliability. Chapter 8 addresses the specific case of getting RDBMS semantics.

Consider transferring from my account at bank A to your account at bank B. That is two transactions that from a business perspective need to succeed or fail together. Now you're right back where we started - just putting an "Activity" label on the client that is stuck holding the bag. Now we're peering under the covers a bit to think about what a process manager or BPM activity is really attempting.

Chapter 8 explains why handling it is not as easy as the RDBMS or BPM abstractions would lead you to believe. In the "easy" case of a classical RDBMS where the whole transaction takes place in a single DB, what happens when the process manager suddenly finds itself out of touch with the database? If the last thing the process manager did was send a commit message without having received a reply from the DB, it doesn't really know whether the transaction was committed or not. Those edge cases manifest themselves in the need for auto-commit or auto-rollback semantics on the database, which in these cases easily can cause the process manager/client not to know the true state of the DB.

It's even more revealing to consider what happens when a classical RDBMS tries to manage a transaction that spans two databases. The technique is called a two-phase commit. It can succeed, it can fail, or it can end with a transaction "in doubt," and blocked until it is resolved.

One of the big differences between reactive applications is they're designed for a scale at which even the edge cases are inevitably going to occur with enough frequency that they need sensible automation. The clients in the "process manager" role have to be coded much more explicitly to understand and react to failures.
jjmargon (11) [Avatar] Offline
Hi again.

Thx for the answer.

Up to know, with "traditional" technologies, I've never worked with Global Transactions (2-phase commit) as they are really heavy.

To keep consistency in the business processes and data in the RDBMS, I've always worked with idempotent steps defined in the business processes and the capacity of this kind of tools (Activity) to recover in case of failure (in the BPM itself or in any of the external systems the process has to work with).

Could you clarify the code example given in the book about the Process Manager about how the client should manage these failure situations?

As it's exposed now, it seems that the BankTransferProcess actor is the analogue to the Activity defined process, instead of the client actor.

Thank you very much and best regards.