Wednesday, November 8, 2017

Software Transactional Memory for the Cloud at µCon London 2017

I have just returned from µCon London 2017: The Microservices Conference. I was down there talking about our Software Transactional Memory implementation which our regular readers may recall was first introduced by Mark back in 2013. In particular I wanted to show how it can be used with the actor model features of Vert.x and the nice scaling features of OpenShift.

I have put the presentation slides in the narayana git repo so feel free to go and take a look to see what you missed out on. You can also access the source code I used for the practical demonstration of the technology from the same repository. The abstract for the talk gives a good overview of the topics discussed:

"Vert.x is the leading JVM-based stack for developing asynchronous, event-driven applications. Traditional ACID transactions, especially distributed transactions, are typically difficult to use in such an environment due to their blocking nature. However, the transactional actor model, which pre-dates Java, has been successful in a number of areas over the years. In this talk you will learn how they have been integrating this model using Narayana transactions, Software Transactional Memory and Vert.x. Michael will go through an example and show how Vert.x developers can now utilise volatile, persistent and nested transactions in their applications, as well as what this might mean for enterprise deployments."

And the demo that this abstract is referring to is pretty trivial but it does serve to draw out some of the impressive benefits of combining actors with STM. Here's how I introduced the technology:

  1. Firstly I showed how to write a simple Vert.x flight booking application that maintains an integer count of the number of bookings.
  2. Run the application using multiple Vert.x verticle instances.
  3. Demonstrate concurrency issues using parallel workloads.
  4. Fix the concurrency issue by showing how to add volatile STM support to the application.

I put the without STM and the with STM versions of the demo code in the same repository as the presentation slides.

I then showed how to deploy the application to the cloud using a single-node OpenShift cluster running on my laptop using Red Hat's minishift solution. For this I used "persistent" STM which allows state to be shared between JVMs and this gave me the opportunity to show some of the elastic scaling features of STM, Vert.x and OpenShift.

Tuesday, November 7, 2017

A comparison of Long Running Actions with a recent WSO paper

By now you will have hopefully heard about a new specification the Narayana team are working on in collaboration with the Eclipse MicroProfile initiative

This specification is tailored to addressing needs of applications which are running in highly concurrent environments and have the need to ensure updates to multiple resources have an atomic outcomes, but where locking of the resource manager has an unacceptable impact on the overall throughput of the system. LRA has been developed using a cloud first philosophy and achieves its goal by providing an extended transaction model based on Sagas. It provides a set of APIs and components designed to work well in typical microservice architectures.

As you might expect, there are a number of other groups looking into these and similar use cases, initiatives such as Eventuate.io [http://eventuate.io/] Axon Framework [http://www.axonframework.org/]. Today I will provide a high-level comparison of the approach taken by the LRA framework with a paper released to the 2017 IEEE 24th International Conference on Web Services - “WSO: Developer-Oriented Transactional Orchestration of Web-Services”.

Web-Services Orchestration (WSO) [http://ieeexplore.ieee.org/document/8029827/] and LRA are both rooted in the compensating transaction models demonstrated in the Sagas paper [http://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf].  Even given their shared grounding in Sagas there are a  number of areas where differentiation can be seen and it would be prudent for the developer to be familiar with these:

1. Ordering of invocations on participants in the transaction

LRA expects that each item is fully dependent on each prior event in the sequence and invokes these in strict order (in the absence of failure). In the case of failure, it uses a Saga-like approach to undo the executed work in reverse order:

 // LRA completion pseudo-code:  
 for (Participant participant : lra.getParticipants()) {  
  if (!participant.complete()) {      
   for (Participant participant : Collections.reverse(lra.getParticipants())  
    if (!participant.compensate()) {  
     // hand this to recovery manager but continue  
    }  
   }  
   break;  

The LRA specification does allow participants to modify this behaviour by allowing them to returning an HTTP "202 Accepted" status code during the completion call and the LRA coordinator will then periodically monitor its progress.

WSO on the other hand allows the transaction scoping to be declared in such a manner as to allow the concurrent execution of individual participants to be performed (pre-compensate). In the case that WSO detects a failure it then appears to use the same approach as LRA.

2. Idempotency

LRA recommends that all compensation and completion handler functions are fully idempotent. This is done to reduce the volume and complexity of the message exchange, and as a consequence makes the model consistent with the Saga principles. This may require the programmer to redevelop their various business operations to guarantee that idempotency property. An alternative approach is available where the handler functions themselves are not idempotent, but an @Status function is provided which can reliably report the current state of the participant and, in companion with the handler functions affects similar idempotency. 

WSO also does not enforce the programmer to develop their business logic with idempotency in mind. To achieve a consistent outcome, the developer is required to build this sophisticated operation with which WSO can probe the resource and try to infer what state the ongoing operation is in.

3. Structure

LRA allows a user to define a Long Running Action which is composed of several participants. Each participant then provides their operation to perform the desired update, plus compensation and confirmation handlers. Although WSO uses different terminology, structuring the transaction is semantically similar.

4. Developer-friendliness

Both LRA and WSO allow the developer to stage migration to their prefered Saga implementation. Out of the box both approaches allow the developer to continue to provide participants that contain only standard business logic, with a view to augment this code with the various additional routines when they are able to do so although LRA does currently mandate the provision of a compensation handler.

5. Locking

As you might expect, both approaches eschew the use of strict resource manager locking between the various participants in their transactions and rely on the compensation framework to reconcile data integrity.

6. Orchestration

The WSO framework provides ability to define strong orchestration of the various participants in an outer transaction. It allows a developer to declare a sequence of participant calls to be made as a result of interim results from the various participants in the orchestration. LRA facilities a similar outcome within its provision of Nested Transactions however achieve orchestration of the participants, LRA requires the developers cooperation to identify and develop those conditional aspects.

In conclusion, as the field of microservice architectures progresses along the path to maturity we are seeing multiple open source projects and vendors respond to the needs of their users by developing frameworks which tend to facilitate atomic outcomes of multiple resources while relax various of the properties we normally expect in transaction system.