Think Before Coding

To content | To menu | To search

Thursday, June 21, 2012

SimpleCQRS the F# version

Here it is ! As promised after greg’s talk at dddx  (you can already see all the presentations online !), a F# version of SimpleCQRS, a simple, quick EventSourcing + CQRS sample to see it in action.

 

Why rewrite it in F# ?

 

This is not just a simple copy of the C# version. The point was first to write it in a functional language, because event sourcing is inherently functional.

 

In C#, an aggregate method looks like this :

 

public void CheckIn(int count)
{
   if(count <= 0)
        throw new InvalidOperationException(
              "must have a count greater than 0 to add to inventory");
   ApplyChange(new ItemsCheckedInToInventory(_id, count));
}

 

The ApplyChange method is defined in the AggregateRoot base class.

It dispatches the event to a state denormalizer and add the Event to uncommitted changes.

 

Here is a denormalizer to apply a state change following an event :

 

private void Apply(InventoryItemDeactivated e)
{
   _activated = false;

 

All this is fine, but why should the aggregate be mutable when the event stream is highly a append only store of immutable events.

 

Watch greg’s talk carefully, both methods can be transformed to an immutable equivalent easily.

 

First the goal of the public method is to determine which event to raise based on command parameters and current state. The CheckIn method can be defined by the following method signature:

int –> State –> Event  or Func<int,State,Event>

 

Instead of calling an Apply change internally, the method simply returns an event :

 

let checkIn count s =
    if count <= 0 then
       raise (InvalidOperationException
           "must have a count greater than 0 to add to inventory")
       fire {ItemsCheckedInToInventory.Id= s.Id; Count = count}

 

where the fire function simply creates a Event array from a single event :

 

let fire o =
    [o :> Event]

(notice the [o:> smiley here !)

An array is returned here so that a method can fire/return several events using a simple :: syntax.

 

The state application can also become immutable. The function gives next state based on event and previous state :

 

State –> Event –> State or Func<State,Event,State>

 

let applyOnInventoryItem s (e: Event) =
   match e with
   | :? InventoryItemCreated as e -> {Id = e.Id; Activated = true }
   | :? InventoryItemDeactivated as e -> {s with Activated = false; }
   | _ –> s

no need for several methods here, every thing is straight forward. Match the event using its type.

The first event is a creation, so a state record is creates.

The second events copies state s with Activated set to false. No change occurs here, a copy is returned.

The _ match specifies that any other event simply return previous state.

 

Done.

 

The current state is a left fold of passed events

Sure and the replayWith method is simply here to do this :

 

let replayWith  =

    Seq.fold

let replayInventoryItem =

    replayWith applyOnInventoryItem { Id = Guid.Empty; Activated = false}

 

the replayInventoryItem is a function that takes a Event seq aka IEnumerable<Event>. It will start with the empty state, then for each event, call the applyOnInventoryItem function with previous state, current event, and iterate with new state.

 

The result is the current state.

 

Command handlers

The event handlers use the following functions :

 

let load id =
   eventStore.GetEventsForAggregate id |>
   replayInventoryItem

let save = eventStore.SaveEvents

let applyOn id version f =
   load id |>
   f |>
   save id version

load simply pass events for the aggregate with identifier id to the replayInventoryItem

save is simply a short cut for the event store SaveEvents method

applyOn loads an aggregate to current state, pass state to f, a function that returns an event seq, then save it to the event store.

 

Here is a sample of its use :

 

member x.Handle (c: CheckInItemsToInventory) =

   checkIn c.Count |>

   applyOn c.InventoryItemId c.OriginalVersion

The checkIn function actually expect an second State argument, it signature is int –> State –> Event seq

 

After passing the c.Count integer argument this is now a State –> Event seq function.

When passed to the applyOn function, the state issued from the load call will be passed to it, resulting in an Event seq that will be passed to the save function.

 

Conclusion

There are a few things to notice in this implementation.

  1. It is very short, much shorter that C# version.
  2. There is no InventoryItem class. The InventoryItem module contains a State record, the representation of the aggregate internal state, functions to determine raised events, and functions to determine next state based on previous state and event. No base class is needed for event dispatch and uncommitted event handling.
  3. There is no repository. Actually the load and save methods do what a repository does, but it’s so simple that no class is required.

I did not talk about the read model that is a bit less interesting here.

Monday, March 5, 2012

Caching done right

I was trolling on twitter Saturday, when I saw tweet by Nate Kohari and some answers :

 

image

I immediately thought :

If you have one problem and use cache to solve it, you now have two problems.

 

Where’s the problem ?

 

The time to retrieve the data is not negligible due to frequency of request and/or time taken by calculation + data access. So we put data to cache so that we don’t have to endure this time on each call.

 

But then comes the problem of cache expiration:

  • We can use a duration.. but what is the acceptable delay ?
  • We can make a check to original data to check if it has changed. It’s more accurate, but incurs a new data access.

Moreover, checking if it changed is often not enough, we also need to find what changed.

 

And deriving what happened from state is basically reverse engineering. I’m an engineer. I prefer forward engineering.

 

 

Let’s do it forward

 

It’s actually easy, it’s the whole point of CQRS.

 

Let’s build a system that raises Domain Events, and we can denormalize events to a Persistent View Model.

 

We just have to listen to events and change the representation we want to send to the users:

  • The events contain everything we need to do fine grained updates easily.
  • We can can compute denormalizations asynchronously if it’s time consuming
  • We can store it in a relational database, a document database, or in memory
  • We can choose any form of denormalization since it’s a denormalization (object graph, but also flat string, json, html …)
  • It will be up to date quickly because it will be updated when the original data changed
  • The first client that makes a request after a change will not endure a cache miss that can be long to process since computing is done on change, and not on request.

A good way to Keep It Simple, Stupid!