Eventual Consistency and Business Alignment

mapI recently discovered through eventual consistency that my bounded contexts were not properly aligned with the business.   I won’t lie, it took me quite a while to make this realization.

This was most likely the case in many situations I’ve had in the past.  Because of this realization, I wanted to let out some of my thoughts about eventual consistency and business alignment.

Dependent Bounded Context

I’ve often encounter situations where a bounded context requires information that another bounded context is responsible for.  I’d like to use a simple example I’ve heard from Udi Dahan.  In the context of an Ecommerce site.

  • A customer can be a defined as a “preferred” customer.
  • Preferred customers receive a 10% discount on all orders.

Based on the above, the “preferred” flag and any business rules associated to it, most likely exists in some sort of the CRM bounded context.  However, this detail is required in the Sales bounded context in order to apply a discount if eligible.

As you can see, there is information that needs to be shared between bounded contexts.

Publish / Subscribe Domain Events

One approach for decoupling your bounded context is to publish domain events from your domain model.  This allows other bounded contexts to subscribe to those events and handle them accordingly.

Let’s use our example above to see how this would be implemented.  In our CRM bounded context, when a customer is defined as preferred in our domain model, we would publish a CustomerIsPreferred event.

class CustomerIsPreferred
{
	public Guid CustomerId { get; private set; }
	public DateTime Date { get; private set; }
	
	public CustomerIsPreferred(Guid customerId, DateTime date)
	{
		CustomerId = customerId;
		Date = date;
	}
}

In our Sales bounded context, we would subscribe to this event and update our customer model with a preferred flag. This piece of information is used as a local cache in our Sales bounded context.

During our checkout process in Sales, we would then use the preferred flag on the concept of a customer in Sales to determine if they should receive a 10% discount.

However, remember that this preferred flag is not owned by Sales.

Because of the publish / subscribe model (assuming asynchronicity), at any given time, our preferred flag in Sales could be out of sync with current state in our CRM bounded context. Eventually consistency doesn’t mean our data is wrong, it just means it is stale.

Business Alignment

There are many situations where data being eventually consistent is totally acceptable.  I’ve found in the real world we often make decisions with stale data all the time.

However, there are times where full consistency is required.  When describing the example above to the business, does the eventual consistency of the preferred flag have true business impact?  If it truly does matter and the data must be fully consistent, then you may have bad business alignment with your bounded contexts.

Re-evaluate your bounded context and the boundaries as you may have an wrong interpretation of responsibilities.

I’ve found that drawing a context map and the events which are published and subscribed with a domain expert should flush out any of these incorrect interpretations and help you re-align boundaries and responsibilities.

CAP Theorem, CQRS and Eventually Consistent

First, if you haven’t heard of Eric Brewer’s CAP theorem, it basically states that you can must choose two of three:

  • Consistency
  • Availability
  • Partition Tolerance

CQRS doesn’t solve CAP issues, however it allows you to decide independently what is important on both read and write side.

For example, you could assume a systems would be ACID (Atomic, Consistent, Isolated, Durable) compliant on the write/domain site and BASE (Basic Availability, Soft-State, Eventually Consistent) on the read side.

Eventual consistency is something that requires a change of mindset.  Because of our heavy use in ACID compliant databases, thinking about possibly having stale data blows our mind.

There are two important points about I want to make about eventually consistent data.

  • The data isn’t wrong.  It’s old.  There is a big difference here.  The data you may be consuming may not be up-to-date, however it was correct at one point in time.
  • In the real world, we use stale data all the time.

A good example, from Greg Young, was if you read the newspaper/website and notice some statistics on the unemployment rate, this is obviously stale data.  If those stats were a a week old, would this matter?  How much of a difference would a week make to unemployment rate?  Probably not much. However, there are scenarios where you want to be much closer to actual, and in these cases define an SLA.

The point is, in many situations, eventually consistent data is acceptable.

Greg Young: 8 Lines of Code

Greg Young gave a good talk titled 8 Lines of Code, discussing simplicity, dependencies, and magic.

Magic is always something I try and identify and stay away from in my own code, however I really failed to realize how much magic goes on in some of the libraries/frameworks that I often use.  Entity Framework and nHibernate come to mind.  You really should understand the magic happening in these libraries to use them.  Which is very problematic.

If you take the dependency ownership seriously, then a lot of folks developing the front-end of a “modern” web applications are in a world of hurt.  RequireJS, Knockout.js, jQuery, Bootstrap, etc, etc, etc…

Video is posted on InfoQ:

http://www.infoq.com/presentations/8-lines-code-refactoring