Sunday, March 23, 2014

Quick and Dirty Command Handlers, Event Handlers, Wiring it Up

In my last post, I talked about a "quick and dirty" way to create a command bus in F#. In this post, we're going to look at a simple set of command handlers to plug into said bus and some event handlers.

Before I jump right in, let's define what we're looking for. I want to use NEventStore for my event bus (comes with some nice features that make getting up and running much faster). Feel free to plug in whatever event store you might feel like. Creating (an extremely basic) event store isn't too terribly hard, but I am not going to cover it in this post. So, without dragging this out too much more, let's create a function that wraps up the creation of NEventStore.

Serializer

NEventStore needs a serializer. It comes with a few baked in, but I have grown fond of FsPickler. It is really fast and convenient since we're using F#. Here's a quick little helper to create our serializer on demand.

Dispatcher

NEventStore also accepts a dispatcher (the thing that is given the events as they come in). Here is where we're going to accept (for now) our event handlers. If needed, as the documentation suggests, we could fire these events off onto a bus like NServiceBus or Mass Transit. All we're going to do (again, for now) is create a function that will return a dispatcher that passes each event to our event handlers. An event handler is just a function that takes a Guid (the entity's id) and a list (ResizeArray) of events.

Create the Event Store

And, finally, we need to create the event store. There is nothing fancy here, it is pretty much just like the example documentation, just using our serializer and dispatcher. It will also use SQL Server as the backing store along with storing the streams in memory.

So, now that we have an event stream, we can push it into our command handlers and extend our setup function from the last post. We're going to change our command handler function to take in bus. We can simply map the original functions and "apply" the event bus, and then pass the resulting functions into the original "createCommandRouter" function.

A simple little domain

Let's take a look at a silly example of a domain, a counter. The counter can be incremented and decremented and that's about it. Since this is all in F#, we'll use a record to define an entity's state and discriminated union to describe the commands and events. This is a pretty common theme if you go hunting around the internet and it has worked out very well for my projects. Our entities will consist of a state, an apply function, and a handle function. (Lev Gorodinski has a really good write-up on this approach and was the basis for my personal "Ah-ha!" moment.)

Now we just need to wire-up our command handler to use the apply and handle functions. Please keep in mind that this is a "Quick and Dirty" solution to get us going and exploring our domain and wiring things up. You will likely need to a function that the handler can call if it encounters and exception and will probably need to rework the domain to return multiple events from commands and then make the appropriate changes in the command handler to handle that. (Simple, really, but too much noise for this post. I will explore these things in a later post.)

Event handlers are just as simple. They can be used to respond to events from your domain and do things like update projections that feed the application. Our "q 'n d" event handler looks something like this:

The DomainStartup

Putting this together, we now get our new domain startup.

This post is already getting long so I will end it here. Have any feedback or questions, please leave them in the comments or hit me up on Twitter. I'd love to hear how you get started quickly on projects to feel productive without building too much cruft.

Saturday, March 8, 2014

Combining F# and Simple.Web to Break SqlEntityConnection

Before we begin, I want to make it absolutely clear that I believe the problem I ran into this week can be attributed, 100%, to PEBKAC.

So, I am creating a new application that is supposed to "enhance" (replace) an internal application and I want to show off how productive F# has been lately. One of the coolest things I've seen with F# are type providers. To connect to the legacy data in this application, I used the SqlEntityConnection and everything was running along smoothly. (I was basically using the type provider as a read-only view of the legacy data, with a few writes here and there.) I ran into a really weird issue that caused me to lose a little bit of time and just want to document it here so I could maybe save future me (or future you) some headache.

I've pushed up a Git repo with a solution that can be run to demonstrate this issue. So, here we go.

The Symptoms

So, I had about 25 Simple.Web handlers firing on all cylinders and, suddenly, one handler would not work. It continued to return a 500 and I couldn't get a breakpoint to catch. Well, I couldn't even get a breakpoint to set. Every one I'd put in gave me an issue saying that symbols were not loaded for the assembly. No matter how much I did "Rebuild All" it would not change. I finally noticed a weird error that looks like this:

A first chance exception of type 'System.NotSupportedException' occurred in FSharp.Core.dll
System.NotSupportedException: LINQ to Entities does not recognize the method 'BlowingUpSqlEntityConnection.Web.Index CheckThis[Index](BlowingUpSqlEntityConnection.Web.Index)' method, and this method cannot be translated into a store expression.
   at Microsoft.FSharp.Linq.QueryModule.CallGenericStaticMethod@337.Invoke(Tuple`2 tupledArg)
   at Microsoft.FSharp.Linq.QueryModule.clo@1741-1.Microsoft-FSharp-Linq-ForwardDeclarations-IQueryMethods-Execute[a,b](FSharpExpr`1 )
   at BlowingUpSqlEntityConnection.Web.Index.getEntity() in C:\Users\James\documents\visual studio 2013\Projects\BlowingUpSqlEntityConnection.Web\BlowingUpSqlEntityConnection.Web\Home.fs:line 15
   at BlowingUpSqlEntityConnection.Web.Index.Simple-Web-IGet-Get() in C:\Users\James\documents\visual studio 2013\Projects\BlowingUpSqlEntityConnection.Web\BlowingUpSqlEntityConnection.Web\Home.fs:line 29
A first chance exception of type 'System.NullReferenceException' occurred in BlowingUpSqlEntityConnection.Web.dll

It's like Entity Framework is trying to run a stored procedure that matches my handler. Weird. Here's what the handler looks like (taken from the available repo).

With a simple change everything worked just fine. By pulling out the Id and making it an parameter of the getEntity function everything went swimmingly.

And now the application is happy as a clam.