Sunday, May 25, 2014

Eventual consistency in the Wild West

San Francisco, 1852. With the California Gold Rush at its peak, successful gold-seekers wanted to protect all their precious gold nuggets by storing them in a strong safe. At the time, it wasn't that easy to have access to a safe though. At the very beginning, it were just a few local merchants that owned one. Not much later, bankers swamped the area hoping to get their piece of the pie - bringing the strongest safes money can buy.

James King of William - who had made a fortune himself mining gold - was one of the first to found a trustworthy bank in San Francisco.
With the city growing from a small 200 residents in 1846 to about 36.000 in 1852, it became harder and harder for the bank to accommodate all their customers in that one office. It needed to expand its operations.
Three months later a new branch opened up on the other side of town. James determined to build a strong brand, wanted to allow customers to go to any of the two branches to deposit and withdraw their money. This meant that the books of the two branches had to be kept consistent. To maintain the books, James commanded all the clerks to duplicate all new records. Two hired horsemen would then come in every few hours and bring those records to the other branch. Since the books were now the same in both branches, customers could deposit and withdraw money in both sides of town. For James, life was good, he was now raking in twice as much.

Pancho and Lefty, two bandits fled from Mexico, trying their luck in California, were instead of spending their Friday afternoon in search of gold, trying to forget their gold drought by playing cards and drinking cheap Whiskey in the local saloon. While Lefty kept rambling on about how unlucky they had been these last few weeks, Pancho paid closer attention to the conversation going on between the saloon keeper and this well-dressed rider that had just entered. The leather bound notebook the rider was carrying stood out immediately - it carried this familiar looking mark and looked expensive. Even though Lefty kept on rambling, Pancho could make up quite a bit eavesdropping on the saloon keeper and the rider's conversation. That suddenly came to an end though, when the rider knocked back his drink and got ready to leave - "Well, I better get going before the boss man notices that his books are no longer up to date."
Pancho watched the rider step outside and get back on his horse. Once the rider was out of sight, Pancho with an intense gleam in his eyes, cut off Lefty and ordered him to shut his mouth - "Shut it fool, I have a plan that's going to make us some easy money."

That same day, Pancho and Lefty gathered all their coins, opened an account for Pancho at James King's bank and made their first deposit. Afterwards, they stuck around the bank's side entrance just to make sure one of the horsemen came by to pick up the books. Twenty minutes later, the same rider they saw at the saloon showed up - Pancho and Lefty spontaneously looked the other way, avoiding to be seen by the rider. They hung around a little longer, to verify that when the driver exited the bank, he was carrying a notebook - a notebook containing the records of the account they just opened and their first deposit.

The next day, Pancho and Lefty got up early. They only got a few hours of shut-eye in, they had been up all night sneaking around, scouting the biggest ranch in town. To make their plan work, they needed to borrow a fast horse.
Impatiently waiting in front of the bank, Lefty breathed a sigh of relief when the clerk opened the bank at nine AM sharp. Before he entered, he looked one more time to the left, where Lefty was standing in the shadows holding the horse - ready to go. Being the first customer to enter the bank, he walked straight up to the counter, pulled out his token of authentication and told the clerk he wanted to make a withdrawal for all that was on his balance. The clerk looked at the token carefully, but didn't ask any further questions - he still remembered seeing Pancho yesterday, it wasn't like he owned a fortune.

Money in hand, Pancho firmly walked out of the bank. To make the plan work, he now needed to jump on that horse as quickly as possible and ride off to the branch on the other side of town - if he made it there before the hired horsemen had the chance to transfer the latest records, he might be able to double his assets in a single morning.

Pancho didn't spare the horse at all, frantically digging his spurs into its sides. He made sure to take the dirt road through town, avoiding obstacles and people where he could.
Tying the horse down next to the bank, he watched one of the horsemen walk out of the bank. Damn. Had he been too slow, were the books already consistent again?
Pancho broke out in a cold sweat, but he had to try. He shuffled into the bank and got in line - there were three customers in front of him. Every time he looked up at the clock, he got more anxious. By the time his turn came, he was terrified. Without looking up, he pulled out his token of authentication once more, and mumbled to the clerk that he wanted to withdraw all of his money. The clerk noticed the drops of sweat on Pancho's forehead and how Pancho's hands were shaking. "Poor soul," the clerk thought, "he must have caught cholera like many others, they're falling like flies." The clerk went into the back, looked into the books, opened the safe and handed Pancho everything he was worth.

James King spent very little of his time at one of his banks - he was too busy looking for new ventures to fund. When he was in town and had the time, he did make a habit of jumping by to look in the books right before closing time. Today, one of the clerks walked up to James King as soon as he arrived; "I'm afraid there has been made a mistake in the books, sir. The books show that one customer withdrew all of his money twice today. First here, and then in the other branch. Something must have gone wrong copying the records." Going through the records, it was obvious to James King what had happened; they had been robbed.

"Thank the lord that it's only for a small amount. Let's make sure this doesn't happen again." James started by hiring two extra horsemen, but to be even more sure he also had to introduce some new rules. A customer could now only withdraw $5 a day, unless he had proven to be a good and reliable customer. If a customer needed to withdraw extraordinary large amounts, he needed to inform a specific branch one day in advance. This allowed both branches to keep serving all customers smoothly while not giving up on operating in a semi-autonomous fashion. James was even considering opening a new branch in the famous city of angels, Los Angeles.

Next time; isolation levels in the Wild West.

Friday, May 16, 2014

NCrafts Eventstorming slides

Me and Tom just finished doing our Event storming workshop at NCrafts Paris. Although we made a few mistakes along the way, feedback on the workshop was great. I hope to put something out about what we learned facilitating later this week. People talked, discovered and eventually learned a new domain in under two hours. The domain? Two minutes before the workshop we found a domain expert prepared to talk about his coupon start-up.
Modeling a business process is often associated with people in suits having long and dull meetings. Way too much time gets wasted for an outcome that's far from reality and which will be obsolete in weeks. Event storming is a workshop format that brings modeling back to all stakeholders, and aims to create usable models.  
In this workshop, you won't be writing any code, but you will be using lots of paper, post-its and a marker. After going over a bit of theory and a small example, we will present you with a real business problem, and in a few short playful sessions you will experience how powerful event storming can be in helping a team gain insight into complex problems.  
The techniques you will learn in this workshop will pay off immediately. 
The slides I used are now up on Slideshare and embedded below.



To learn more, you can join the EventStormers community, but more importantly, you should start experimenting yourself!

Monday, May 12, 2014

What if we stored events instead of state? - slides

I just returned from Croatia, where I got to speak twice at the second edition of The Geek Gathering.

Being such a young conference, I had no idea what to expect really. Turns out they have a good thing going on; a small, local and very personal approach to conferences. Speakers both local and international, covering topics that serve the community, not their employer.

Together with Tom, I preached Alberto's Event Storming during a four hour long workshop. As always, people were impressed by how quick you can gain an understanding of a new domain using this technique. Slides of this workshop will be online after I make some tweaks, and try it in Paris on Friday.

In my second talk, I got to share what I've learned these last two years on event sourcing. You can find the slides of that talk embedded below or on Slideshare. Thanks Tom, Mathias, Stijn, Yves and Bart for reviewing them!


Sunday, May 4, 2014

Glueing the browser and POS devices together

I have been occupied building a modest Point of Sale system over these last few weeks. Looking at implementing the client, there were two constraints; it needed to run on Windows and it should be able to talk to devices such as a ticket printer and a card reader.

Although we could use any Windows client framework, we like building things in the browser better for a number of reasons; platform-independence, familiar user experience, JavaScript's asynchronous programming model and its incredible rich ecosystem. Having to talk to devices ruled out leveraging the browser to deliver our application though - or didn't it?

Most Windows client frameworks give you a browser component which can be used to host web applications inside of your application. We used this component to host our web application, which turned the hosting application into not much more than a bridge between our web application and the devices.

This bridge processes commands sent by the browser (or the application itself), and produces events which are returned to the browser. I ended up not needing much code to implement this.

I defined two thread-safe queues - one to put commands on, and one to put events on. 
private readonly BlockingCollection<ICommand> _commandQueue = 
    new BlockingCollection<ICommand>(); 
private readonly BlockingCollection<IEvent> _eventQueue = 
    new BlockingCollection<IEvent>();
Then I start consuming the command queue in the background by turning it into an observable and subscribing to it. Processing commands in the background ensures that command processing never blocks the UI thread.
Task.Factory.StartNew(() =>
{
    var processor = new CommandProcessor(_eventQueue);

    _commandQueue
        .GetConsumingEnumerable()
        .ToObservable()
        .Subscribe(processor.Execute);
});
When a command is dequeued, the associated handler will be invoked. The handler then does its work while raising events when appropriate.
public class DoSomethingHandler : IHandle<DoSomething>
{
    private readonly BlockingCollection<IEvent> _eventQueue;

    public SleepCommandHandler(BlockingCollection<IEvent> eventQueue) 
    {
        _eventQueue = eventQueue;
    }

    public void Execute(DoSomething cmd)
    {
        _eventQueue.Add(new DoingSomething());

        // do work

        _eventQueue.Add(new FinishedDoingSomething());
    }
}
In the meanwhile the event queue is being processed in the background as well - sending events to the browser as fast as they can be dequeued.
Task.Factory.StartNew(() =>
{
    _eventQueue
        .GetConsumingEnumerable()
        .ToObservable()
        .Subscribe(SendToBrowser);
});
Sending events to the browser is done by invoking a script through the browser control.
private void SendToBrowser(IEvent @event)
{
    object[] args = { string.Format("app.bus.send({0})", EventSerializer.Serialize(@event)) };

    if (WebBrowser.InvokeRequired)
    {
        WebBrowser.BeginInvoke((MethodInvoker)delegate
        {
            if (WebBrowser.Document != null)
                WebBrowser.Document.InvokeScript("eval", args);
        });
    }
    else
    {
        if (WebBrowser.Document != null)
            WebBrowser.Document.InvokeScript("eval", args);
    }
}
In the browser, we can now transparently subscribe to these events. As an implementation detail on that side, we're using Postman for pub-sub in the browser.

With this, we've come full circle; commands come in, they get processed, leading to events being produced, which eventually go out to the browser.

With this, we provide a consistent web experience for users and for developers, while not having to jump through too much hoops to make it work.


I also thought of hosting communication with the devices in a Windows service while having that component expose its functionalities over HTTP so that the browser could talk to a local endpoint instead of being hosted in an application. While this is a valid alternative, it raised some concerns towards deployment in our scenario (we can't push changes towards these clients, they need to come get them). With the existing set-up, I think even if we would like to change to such a model, it wouldn't be that much trouble.

If you've pieced together a similar solution, feel free to let me know what I'm getting myself into.