Why you should give Marten a look before adopting an ORM like EF

Of course this post is displaying my bias, but hell, I wouldn’t have spent almost a year working so hard on Marten if I didn’t believe in the concept and its advantages over other .Net persistence tools. In no way am I actually criticizing Entity Framework or Dapper in this post, but I am trying to  bluntly say that the days of ORM’s and even micro-ORM’s needs to come to a close soon.

Last week I got to pull the trigger on Marten 1.0. This week I think it’s time to talk about why and when you would want to use Marten as your persistence strategy in .Net development. Most of the early interest and adopters of Marten have been disaffected users of RavenDb looking for a more reliable alternative who were already sold on the idea of a document database (and here’s me from a month ago on moving from RavenDb to Marten). That’s great and all, and it got our community jump started, but I think Marten deserves a longer look from developers who aren’t already using document databases like RavenDb or MongoDb today.

I’ve written about my thinking about how I choose persistence tools before. I’ve also spoken out many times about the never ending attempts to keep business logic code from being compromised by coupling it directly to your database storage. Finally, there’s the old discussions about “persistence ignorance” from years past.

Consistent with my beliefs and experience with software development, I feel like the document database approach for most of your application persistence makes the most sense for developer productivity, automated testing support, and ease of deploying application code changes. Yes, please do consider Marten as a replacement or alternative to MongoDb or RavenDb because it’s built on the more reliable and performant Postgresql foundation. But also, give Marten a serious look as an alternative to using the Entity Framework, NHibernate, or any of the plethora of micro-ORM projects out there.

Why you would choose Marten over EF

  • Much less mechanical work for mapping and configuration. Far less effort for schema management and database migrations.
  • Higher “reversibility” in your software architecture because it’s so much easier to change the structure of your documents with Marten versus an ORM of any kind.
  • Marten is built on Postgresql and gets to take advantage of their very advanced JSON features. Postgresql is highly performant, widely used, runs cross platform, and it’s FOSS.
  • Being able to use embedded Javascript functions inside of Postgresql gives Marten a potentially far better story for creating read side views of complex data than any kind of ORM access plus AutoMapper type tooling.
  • Marten is going to be able to handle hierarchical data and storing subclassed documents much easier than any ORM ever could. Moreover, Marten will easily outperform an ORM fetching any kind of aggregated, deep object because there’s just far less stuff that Marten has to do compared to an ORM like EF.
  • Marten allows you to mix and match persistence strategies. Document storage? Check. Event sourcing persistence? Got that too. Wanna use straight up SQL or even integrate directly with Dapper in Marten database transactions? We’ve got that one covered as well. Heck, if you wanted to do full text searching or do key/value storage, you can use Postgresql features to get that done all in one single bit of infrastructure.
  • Using value types is trivial in Marten. As long as your JSON serializer can handle your type, you’re good to go with no crazy gymnastics like ORM’s cause.
  • I think that Marten’s compiled query feature is hands down better than EF’s solution for reusing Linq query parsing, and that’s goint to make a significant difference in application performance under a load.

Why you would choose EF over Marten

  • You don’t have any experience with Postgresql
  • The full weight of Microsoft is behind EF whereas Marten is a community OSS project. My company is de facto sponsoring Marten and I have a track record for sticking with my OSS projects for a long time, but EF has a whole team behind it.
  • EF’s Linq support is going to be more complete than Marten’s — but we’re certainly trying on that front.
  • Entity Framework and relational databases are very well known and it’s easy to find folks who are familiar with them. Like it or not, that has to be part of your thinking about choosing any tool.
  • More documentation, samples, and a larger development community than any OSS tool in .Net could ever attract.
  • Your shop simply favors Sql Server or uses cloud hosting providers that only support Sql Server. We’re frequently getting the feedback from developers that they’d like to use Marten but that their database teams won’t allow Postgresql. I think that there will eventually be a version of Marten on Sql Server, but that’s dependent upon Sql Server getting better JSON support than what’s coming in MSSQL 2016.
  • You can still use straight up SQL to access your Entity Framework persisted data if that’s valuable. You can do that with Marten as well, but the Postgresql JSON operators aren’t the most approachable thing in the world.

 

About ORM’s

A decade ago I strongly espoused Object Relational Mapping (ORM) tools like NHibernate  as the “best” tool to allow us to build our application code in a way that made sense for the application logic and still be able to persist state to a relational database. Great, and that was arguably better than the morass of purely procedural code and wretched stored procedure data access that came before. After using ORM’s for five years, then another five years of predominantly using document databases, I don’t ever want to go back to ORM’s.

Why? Because ORM’s are a giant mess to use if your object model deviates much from the structure that makes sense in the database — and it usually does. I’m sick of wasting time trying to remember to make every member virtual for dynamic proxies, sick of having to worry about lazy vs eager loading, and having to duplicate so much logical work to keep the application code synchronized to the database schema. I absolutely prefer the productivity we get from document database approaches where we just store a JSON representation of our document objects with minimal work for mapping.

While the classic analogy for ORM’s is Ted Neward’s seminal blog post on ORM’s are the Vietnam of Computer Science, the analogy I would use is that ORM’s are like Prius’s. I think they were only an overly complicated, intermediate solution until we came up with better approaches. Much the way that hybrid cars are a stepping stone to fuel cell or pure electric cars and Obamacare should be a temporary measure until we get our acts together and adopt a rational single payer healthcare system, ORM’s are just a less bad idea than what came before.

 

 

I helped write the EF Vote of No Confidence once upon a time, and while I to this day think that the initial version of the Entity Framework should have never been released, I don’t actually have any issue with the current versions of EF and how it implements object relational mapping. I’m just objecting to the whole concept of ORM’s now;)

 

What about Micro-ORM’s?

I occasionally see one of the main developers on Dapper pooh-pooh’ing IoC containers like StructureMap.* That’s okay though because I have the exact same “meh” attitude toward micro-ORM’s. I think they couple your application way too tightly to your database structure and they seem to let database concerns bleed into your application code more than I’d prefer. Again, the problem with ORM’s is the “R” more than how the “M” is done.

It’s a moot point though, because you can happily use Dapper in conjunction with Marten by just calling Dapper methods on the exposed connection property of Marten sessions — which was done explicitly to enable this interaction.

 

 

* I don’t feel strongly enough to even argue the pro-IoC container side of things. I’ve thought about kicking out a blog post titled “A tepid defense of IoC containers.” My own usage of StructureMap is pretty simple anyway.

Storyteller 3.0 Official Release — and on to 4.0

I was able to finally cut an official Storyteller 3.0 release to Nuget at the end of last week with a few fixes. Storyteller is a tool for writing and running executable specifications (BDD, if you absolutely have to call it that), end to end automated testing, and a separate function for generating technical documentation websites that I’ve used for StructureMap, Marten, and Storyteller itself.

Some links with a whole lot more information:

I’ve done two conference talks about Storyteller in the last year but both of the videos were never posted. I’ve had rotten luck with this lately:( I *might* be doing a talk about the building of the Storyteller client with React.js at CodeMash.

 

Onward to 4.0!

With Marten settling down after its 1.0 release, I’ve been able to devote much more time to Storyteller and the 4.0 release is well underway. While there are worlds of little GitHub issues to knock down, the big themes for 4.0 are to:

  1. Get Storyteller running cross platform using the CoreCLR. I blogged about my plans for pulling this off a couple weeks ago, and as of last week I’m able to run Storyteller locally on Mac OSX. I’ll be writing a follow up experience report post soon, but the summary is “so, that sucked.”
  2. Fully embrace the dotnet CLI and create a dotnet test adapter for Storyteller to make it far easier for developers to run and debug Storyteller specifications
  3. The “step through” model of executing specifications when troubleshooting failing specs. This is partially done now, but there’s plenty to do on the UI client side before it’s really usable.
  4. Extend the reach of Storyteller by allowing users to author the specification language on the fly in the specification editor without having to first write C# code. My hope is that this feature will make Storyteller much more effective as a specifications tool. This had been a goal of the 3.0 release, but I never got to do it.
  5. Enhance the performance testing and diagnostic support in Storyteller today. Maybe the most popular feature of Storyteller is how it captures, correlates, and displays information about the system performance during spec execution. I’d like to take this farther with possible support for gathering benchmark data and allowing teams to express non-functional requirements about performance that would cause specifications to fail if they’re too slow.
  6. Potentially, be able to use the existing Storyteller specification editor and runner against completely different testing engines written for other languages or platforms

More coming this fall…

Marten 1.0 is Here!

banner

Marten is an open source library hosted on GitHub that makes the rock solid Postgresql database usable within .Net systems as a fully fledged document database. On top of that, we also built event store functionality with support for read side projection generation. By adopting Marten and Postgresql on your project, you’ve got a one stop shop for document storage, event sourcing, classic relational database usage, and even key/value storage in one single database engine.

I was able to push the official Marten 1.0 release today to Nuget. As of now, I’m fully ready to stand behind Marten as production ready. We have some early adopters using Marten in production now, my own shop is well underway with an effort to migrate our largest application to Marten, and I know of a couple other teams developing against Marten today. Now that the big “1.0” version is out, we will be honoring semantic versioning rules from here on out for backwards compatibility. It’s almost a 100% certainty that there’s going to be another nuget release next week with some small additions and whatever bug fixes inevitably spill out of the 1.0 release.

This is the culmination of almost a solid year of effort from myself and many others. Marten is de facto sponsored as an OSS project by my employer and several of my colleagues have made contributions as well. I’ve said for quite a while now that Marten has been the most positive experience I’ve ever had developing an OSS project and I greatly appreciate the Marten community. By doing this project in public, I feel like my company has been able to get valuable feedback on usability, the necessary features we need to perform well, and a lot of critical bugs detected and fixed much faster than I think we could have done if we’d built this in private.

I’ll follow up this blog post and try to make the case for why and when a team should choose Marten over the other options for persistence. Marten has been driven from the very beginning as a replacement for RavenDb in our architecture at work, but I’ll also try to make the case for why your team could be more productive with the Marten/Postgresql combination than an ORM like EF or NHibernate and even micro-ORM’s. We do need to provide a lot more information and samples for using the event store functionality that I’ll try to blog out as we get that pulled together.

I’d like to thank…

  • My colleague Corey Kaylor for helping create the vision and doing so much work in our build automation. Thank Corey if you like having CoreCLR support or the compiled query feature
  • Nieve for doing a lot of work on Marten’s Linq support, among other things
  • Tim Cools for pushing the event store functionality and our identity map mechanics
  • Evgeniy Kulakov for getting the async functionality started
  • Daniel Marbach for doing so much work to help us improve Marten’s async support
  • Jens Pettersson for lots of feedback, suggestions, and help with Marten’s bulk insert story
  • Phillip Haydon for being our biggest advocate, providing a lot of guidance on Postgresql, and driving the design of many features
  • Khalid Abuhakmeh for doing the graphics on the website and helping with the event store
  • Brady Clifford and company for doing the heavy lifting to make Marten fit into our application architecture at work
  • A whole host of other contributors and folks who have raised or commented on issues for us. The level of community interest and feedback I’ve seen has been unprecedented to me in my 12 years of doing OSS work in .Net.

 

Some links

 

 

 

If you’re interested, or know somebody who would be, I am able to take on short term consulting projects for Marten as side work. 

Building Marten’s Async Daemon

A couple weeks ago I wrote a blog post on the new “Async Daemon” feature in Marten. This post is a bit that I cut out of that post just describing the challenges I faced and what I did to slide around the problems. For all Marten users that have been asking me about writing their own subsystem to read and process events offline, you really want to read this post to understand why that’s much harder than you’d think and why you do probably want to just help make the async daemon solid.

The first challenge for the async daemon was “knowing” when there are new events that need to be processed by async projections. When a projection runs, it needs to process the events in the same order that they were captured in. Since the async daemon was inevitably going to use some sort of polling (NOTIFY/LISTEN in Postgresql was not adequate by itself) to read events out of the event table, we needed a very efficient way to be able to page the event fetching without missing events.

We started Marten with the thought that we would try to accomplish that by having the event store enqueue the events in a rolling buffer table that some kind of offline process would poll and read, but we were talked out of that approach in discussions with a Postgresql consultant who was helping us at work. Moreover, as I worked through other use cases to rebuild projections from scratch or add new projections later, we realized that the rolling buffer table would never have worked for the async daemon.

We also experimented with using sequential Guid’s as the global identifier for events in the event store with the idea that we would be able to use that to key off of for the projections by always querying for “Id > [last event id encountered].” In my testing I was unable to get the sequential Guid algorithm to accurately order the event id’s, especially under a heavy parallel load.

In the end, we opted to make the event store table in Marten use a sequential long integer as its primary key, and backed that with a database SEQUENCE. That gave us a more reliable way to “know” what events were new for each individual projection. In testing I figured out pretty quickly that the async daemon was missing events when there’s a lot of concurrent events streaming in because of event sequence id’s being reserved from in flight transactions. To counteract that problem, I ended up taking a two step process:

  1. Limit the async daemon to only querying against events that were captured before some time of threshold (3 seconds is the default) to avoid missing events that are still in flight
  2. When the async daemon fetches a new page of events, it actually tries to check that there are no gaps in the event sequence, and if there is, it pauses a little bit, and tries again until there are no gaps in the sequence or if the subsequent fetch turns up the exact same data (leading the async daemon to believe that the missing events were rejected).

Those two steps — as far as I can tell — have eliminated the problems I was seeing before about missing events in flight. It did completely ruin a family dinner at our favorite Thai restaurant when I couldn’t make myself stop thinking about how to slide around the problems in event ordering;)

The other killer problem was in trying to make the async daemon resilient in the face of potential connectivity problems and occasional projection failures without losing any results. I’ll try to blog about that in a later post.

 

 

 

Moving Storyteller to the CoreCLR and going Cross Platform

This is half me thinking out loud and half experience report with new .Net new world order. If you want to know more about what Storyteller is, there’s an online webinar here or my blog post about the Storyteller 3 reboot and vision.

Storyteller 3 is an OSS acceptance test automation tool that we use at work for executable specifications and end to end regression testing. Storyteller doesn’t have a huge number of users, but the early feedback has been mostly positive from the community and it gets plenty of pull requests that have helped quite a bit with usability. Not that my Marten work is settling down I’ve been able to start concentrating on Storyteller again.

My current focus for the moment is making Storyteller work on the CoreCLR as a precursor to being truly cross platform. Going a little farther than that, I’m proposing some changes to its architecture that I think will make it relatively painless to use the existing user interface and test runners with completely different, underlying test engines (I’m definitely thinking about a Node.js based runner and doing a port of the testing engine to Scala or maybe even Swift or Kotlin way down the road as a learning exercise).

My first step has been to chip away at Storyteller’s codebase by slowly replacing dependencies that aren’t supported on the CoreCLR (this work is in the project.json branch on Github):

Current State Proposed End State
  • Targets .Net 4.6
  • Self-hosted w/ Nowin
  • FubuMVC for the web application
  • Fleck for web sockets support
  • Tests execute in a separate AppDomain with all communication done via sending Json messages through .Net Remoting
  • FubuCore for the command line parsing
  • Uses Fixie for unit testing
  • RhinoMocks for mocking
  • Csproj/MSBuild for compiling, Paket for Nuget management
  • A single Nuget for the testing engine library and the test running/documentation generation executable
  • No Visual Studio or VS Code integration
  • Targets .Net 4.6 and the CoreCLR
  • Self-hosted with Kestrel
  • Raw ASP.Net Core middleware
  • Kestrel/ASP.Net Core for Websockets
  • Tests will execute in a separate process, and the communication between processes will all be done with sockets
  • Using Oakton for the command line parsing
  • Uses xUnit for unit testing
  • NSubstitute for mocking
  • The dotnet CLI for CI builds and all Nuget management, project.json for all the projects
  • A nuget for the .Net testing engine library, a second one for the command line tooling for specification running and editing, a third nuget for the documentation generation
  • A fourth nuget for integrating Storyteller with dotnet test
  • A VS Code plugin?

Some thoughts on the work so far:

  • Kestrel and the bits of ASP.Net Core I’m using have been pretty easy to get up and going. The Websockets support doesn’t feel terribly discoverable, but it was easy to find good enough examples and get it going. I was a little irritated with the ASP.Net team for effectively ditching the community-driven OWIN specification (yes, I know that ASP.Net Core supports OWIN, but it’s an emulation) for their own middleware signature. However, I think that what they did do is probably going to be much more discoverable and usable for the average user. I will miss referring to OWIN as the “mystery meat” API.
  • I actually like the new dotnet CLI and I’m looking forward to it stabilizing a bit. I think that it does a lot to improve the .Net development experience. It’s an upside down world when an alt.net founder like me is defending a new Microsoft tool that isn’t universally popular with more mainstream .Net folks.
  • I still like Fixie and I hope that project continues to move forward, but xUnit is the only game in town for the dotnet CLI and CoreCLR.
  • Converting the projects to the new project.json format was relatively harmless compared to the nightmare I had doing the same with StructureMap, but I’m not yet targeting the CoreCLR.
  • I’ve always been gun shy about attempting any kind of Visual Studio.Net integration, but from a cursory look around xUnit’s dotnet runner code, I’m thinking that a “dotnet test” adapter for Storyteller is very feasible.
  • The new Storyteller specification editing user interface is a React.js-based SPA. I’m thinking that that architecture should make it fairly simple to build a VS Code extension for Storyteller.

 

The Killer Problem: AppDomain’s are Gone (for now)

Storyteller, like most tools for automating tests against .Net, relies on AppDomain’s to isolate the application under test from the test harness so that you can happily rebuild your application and rerun without having to completely drop and restart the testing tool. Great, and other than .Net Remoting not being the most developer-friendly thing in the world, that’s worked out fairly well in Storyteller 3 (it had been a mess in Storyteller 1 & 2).

There’s just one little problem, AppDomain’s and Remoting are no longer in the CoreCLR until at least next year (and I’m not wanting to count on them coming back). It would be perfect if you were able to unload the new AssemblyLoadContext, but as far as I know that’s not happening any time soon.

At this point, I’m thinking that Storyteller will work by running tests in a completely separate process to be launched and shut down by the Storyteller test running executable. To make that work, users will have to make their Storyteller specification project be an executable that bootstraps their system under test and then pass an ISystem object and the raw command line parameters into some kind of Storyteller runner.

I’ve been experimenting with using raw sockets for the cross process communication and so far, so good. I’m just shooting json strings back and forth. I thought about using HTTP between the processes, but I came down to just feeling like that would be too heavy. I also considered using our LightningQueues project in its “ZeroMQ” mode, but again, I opted for lighter weight. The other advantage for me is that the “dotnet test” adapter communication is done by json over sockets as well.

I think this strategy of running separate processes would make Storyteller a little more complicated to set up compared to the existing “just make a class library and Storyteller will find your custom ISystem if one exists” strategy.  My big hope is that the combination of depending on a separate command line launched process and shooting json across sockets will make it much easier to bring on alternative test running engines that would be usable with the existing Storyteller user interface tooling.

 

 

 

Proposed Roadmap for Marten 1.0 and Beyond

I’m just thinking out loud here and hoping for some usable feedback.

I feel like Marten is getting very close to an official 1.0 release, and the latest Nuget is marked as 1.0-alpha. The Marten community voted on our minimum feature set for 1.0 earlier this year and we’ve finished everything on that list as of late July (right before I went on a long family vacation;)).

Some thoughts on the big 1.0:

  • I’m a big believer in semantic versioning, so an OSS tool reaching 1.0 is a big deal because that starts the draconian versioning rules about backward compatibility. You want to get pretty close to a livable API before you throw that switch to 1.0.
  • It’s a chicken and egg kind of conundrum. What we need right now is more users spawning yet more feedback about Marten. I’d love to have more usage before flipping Marten to 1.0, but we’ll get a lot more users after we release it as 1.0.
  • In this day and age of package managers like Nuget, it’s a lot less friction to make more frequent releases and update your dependencies, so going 1.0 now knowing that 1.0.* bug fix releases and 1.* feature releases will be coming soon just isn’t that worrisome.
  • I feel pretty good about the document database side of Marten, but the event store functionality is still churning and it’s less mature.
  • We’re basically out of low hanging fruit kind of features on the document storage and Linq support
  • My shop is doing the work right now to transition a very large web application from RavenDb to Marten. Right now I’m thinking that the first version of Marten that goes into production across all of that application will be declared to be 1.0.

All that being said, my best guess for an official Marten 1.0 release is around October 1st. Right now my biggest issues on my plate are really all around schema management and our database team’s requirements for the DDL generation. And more documentation, but that battle never ends. Plenty of pull requests are still flowing in, but I think I’m personally done with any kind of major feature work for awhile unless there’s noticeable demand from the community for specific features.

 

Marten 1.1 and Beyond

Based on our current issue list and requests from the Marten Gitter room, I think this list is where Marten goes next after the 1.0 release:

  • Better support for child collections on documents
  • More types of event store projections — if you’re looking to get into doing some OSS work, I think these are our most approachable stories in the backlog
    • Project to a flat table for better reporting?
    • Projections that use the output of other projections
    • Arbitrary categorization of projected views (by customer, by region, etc.). Some of our users have already done this themselves, but it’s not in Marten itself yet
  • Multi-tenancy support. My thinking right now is that we don’t directly put this into Marten, but make sure that there are adequate hooks to do this easily yourself. There’s a lot more information in the GitHub issue linked to above.
  • Possibly try to support the Linq GroupBy() operator. That might also lead into some kind of map/reduce capability within Marten. We’ve had the feedback that “Marten isn’t a real document db because it doesn’t have map/reduce.” I think that’s nonsense, but we might very well need to have a better story for creating aggregated views into the document state — which may or may not be best done as some kind of formal map/reduce strategy.
  • More support on document structural changes. Marten can already handle transformations of a single document type, but we’ll need to be able to later address document type names being changed, multiple document types getting combined (this is potentially a big deal for one of our systems), and whatever else we bump into next spring when we start optimizing a big system at work;)
  • Being able to do document transformation with more than one document at time. This would mean being able to use related documents in the same Select() transformation. Also, we’ll probably need to be able to use Javascript transformations across multiple document types.

There’s some other things in the GitHub issue list, but the above is what I’m thinking about right now for 1.1 and beyond.

Thoughts? Concerns? Requests? Let us know either here, the GitHub issue list, or the Marten Gitter room.

 

Proposed Marten Tooling for Database Management

This is an update to an earlier post on schema management using Marten.

At this point, I think the biggest challenges facing us at work for using Marten are strictly in the realm of database change management. To that end, we’re adding what will be a new package for command line tooling around Marten schema management and investigating possible usage of Sqitch to handle database migrations in our ecosystem. The command line usage shown in this post is in Marten master, but not pushed up to Nuget in any way yet. The Sqitch usage here is purely hypothetical.

When you’re using Marten, all the data definition language (DDL) for the underlying Postgresql database is generated to match by code within Marten. In development, you’d just run with the setting to auto-create database objects on the fly to match the code for faster iteration. For production deployment, however, you probably don’t get to do that and you’ll need some kind of database migration strategy to get the changes that your Marten application needs to the real database. That’s the gap that this post is trying to fill.

 

Command Line Tooling

My concept for supporting command line tooling suitable for build automation at this point is to publish a new library package called Marten.CommandLine that you can use to expose your own application and database through the command line. To use this tooling, follow these steps:

  1. Create a new console application in your solution
  2. Add the forthcoming Marten.CommandLine nuget
  3. Add a reference to the projects in your system that would express the configuration for your Marten-enabled application
  4. In the “Main()” entry point of your new console application, add code like this below to build up your Marten configuration via the StoreOptions class and then delegate to Marten to parse the command line arguments and execute the proper command:
    public class Program
    {
        public static int Main(string[] args)
        {
            var options = buildStoreOptions();

            return MartenCommands.Execute(options, args);
        }

        private static StoreOptions buildStoreOptions()
        {
            // build your own StoreOptions that 
            // establishes the configuration of your
            // Marten application
        }
    }

You can see an example of building the console application from the SampleConsoleApp project I used in the Marten codebase to test this functionality.

Once you have the code above, you’re actually ready to go. If you’re using the new dotnet CLI, running “dotnet run” in the root of your console application project yields this output listing the valid commands:

------------------------------------------------------------------------------------------------------------------------------------

  Available commands:
------------------------------------------------------------------------------------------------------------------------------------

   apply -> Applies all outstanding changes to the database based on the current configuration
  assert -> Assert that the existing database matches the current Marten configuration
    dump -> Dumps the entire DDL for the configured Marten database
   patch -> Evaluates the current configuration against the database and writes a patch and drop file if there are any differences
------------------------------------------------------------------------------------------------------------------------------------

 

If you’re not using the dotnet CLI yet, you’d just need to compile your new console application like you’ve always done and call the exe directly. If you’re familiar with the *nix style of command line interfaces ala Git, you should feel right at home with the command line usage in Marten.

For the sake of usability, let’s say that you stick a file named “marten.cmd” (or the *nix shell file equivalent) at the root of your codebase like so:

dotnet run --project src/MyConsoleApp %*

All the example above does is delegate any arguments to your console application. Once you have that file, some sample usages are shown below:

# Assert that the database matches the current database. This
# command will fail if there are differences
marten assert --log log.txt

# This command tries to update the database
# to reflect the application configuration
marten apply --log log.txt

# This dumps a single file named "database.sql" with 
# all the DDL necessary to build the database to
# match the application configuration
marten dump database.sql

# This dumps the DDL to separate files per document
# type to a folder named "scripts"
marten dump scripts --by-type

# Create a patch file called "patch1.sql" and
# the corresponding rollback file "patch.drop.sql" if any
# differences are found between the application configuration
# and the database
marten patch patch1.sql --drop patch1.drop.sql

In all cases, the commands expose usage help through “marten help [command].” Each of the commands also exposes a “–conn” (or “-c” if you prefer) flag to override the database connection string and a “–log” flag to record all the command output to a file.

 

My Current Thinking about Marten + Sqitch

Our team doing the RavenDb to Marten transition work has turned us on to using Sqitch for database migrations. From my point of view, I like this choice because Sqitch just uses script files in whatever the underlying database’s SQL dialect is. That means that Marten can use our existing “WritePatch()” schema management to tie into Sqitch’s migration scheme.

The way that I think this could work for us is first to have a Sqitch project established in our codebase with its folders for updates, rollbacks, and verify’s. In our build script that runs in our master continuous integration (CI) build, we would:

  1. Call sqitch to update the CI database (or whatever database we declare to be the source of truth) with the latest known migrations
  2. Call the “marten assert” command shown above to detect if there are outstanding differences between the application configuration and the database by examining the exit code from that command
  3. If there are any differences detected, figure out what the next migration name would be based on our naming convention and use sqitch to start a new migration with that name
  4. Run the “marten patch” command to write the update and rollback scripts to the file locations previously determined in steps 2 & 3
  5. Commit the new migration file back to the underlying git repository

I’m insisting on doing this on our CI server instead of making developers do it locally because I think it’ll lead to less duplicated work and fewer problems from these migrations being created against work in progress feature branches.

For production (and staging/QA) deployments, we’d just use sqitch out of the box to bring the databases up to date.

I like this approach because it keeps the monotony of repetitive database change tracking out of our developer’s hair, while also allowing them to integrate database changes from outside of Marten objects into the database versioning.

 

 

Moving from RavenDb to Marten

EDIT 8/19: Couple other things came up about indexing yesterday that I added here.

For the purpose of this post, I’m only talking about the document database features in Marten. Our immediate need is to replace RavenDb before our busy season starts. Using the event store half of Marten probably won’t happen for us until next year.

The planets have finally aligned for us at work to begin converting our largest and most active application from RavenDb to Marten for persistence. I’m meeting with a couple of our teams this morning to talk over the transition, and this blog post is just an attempt to get my talking points prepared for them.

Moving to Marten

First off, Marten is really just a fancy data access library against the outstanding Postgresql database engine. Marten utilizes Postgresql’s JSONB type to efficiently store and query against our document data. We have deliberately based some of the most basic API usage on RavenDb where that made sense in order to make the transition to Marten easier for our teams, but Marten has deviated quite a bit in more advanced usage.

Here’s what I want our teams to know when we switch things over:

  • Marten is ACID all the way down. No more WaitForNonStaleResults() nonsense, no more subtle bugs or unstable automated tests from stale data. Some folks have poked back at this in Marten by claiming that eventual consistency is necessary for performance or scalability. So far, all our experimentation suggests that Marten’s Postgresql-backed writes – with ACID – are measurably faster than RavenDb.
  • Marten does not force you to declare which indexes you want to use for any given query. Postgresql itself can figure out the most efficient execution plan for itself. This is going to be advantageous for us in a couple ways. First by letting us rip a lot of RavenDb index code out. Secondly by making it much easier to optimize database performance without having to have so much impact on the code like it is today with RavenDb.
  • We need more documentation and blog posts on this topic, but it is perfectly possible to use the relational database features of Postgresql where that’s still valuable.
  • If it’s useful, it is possible to use Dapper in conjunction with Marten and even in the same unit of work/transaction.
  • Just like RavenDb, Marten’s IDocumentSession is effectively the unit of work and should be scoped to a logical transaction. In most cases in our systems that effectively translates to an IDocumentSession per HTTP request or service bus message.
  • There is no hard request throttling in Marten. You should be aware of how many network round trips you’re making during a single operation and there are diagnostics to track that, but Marten will not blow up in production because an operation happened to make too many requests.
  • There’s no equivalent to RavenDb’s embedded data store option. That was the killer feature in RavenDb we’re going to miss the most. Fortunately, it’s pretty easy to spin up Postgresql on your own box. For automated testing scenarios where today we just use a brand new RavenDb data store, we’ll just take advantage of Marten’s “database cleaner” to wipe out state in between tests. In a way, this will simplify some of our testing against distributed systems. If this becomes a problem for test performance, we have a couple fallback plans to either host Postgresql in disposable Docker images or to enhance our testing harnesses to leapfrog clean schemas between tests.
  • Most importantly, if there’s something in Marten you don’t like, you can either do a pull request or at least raise an issue in GitHub where I’ll see it and we can get it fixed. OSS FTW!
  • We don’t use this in our internal systems (but we should), but the “Include()” feature in Marten for fetching related documents in one round trip is quite different than Raven’s.
  • Batch querying in Marten is more explicit and different mechanically than RavenDb’s “Futures.” We should be using this feature to reduce network chattiness between applications and the database.
  • I am highly recommending the usage of the Compiled Query feature in Marten that has no equivalent in RavenDb for better runtime performance and even as a declarative query model. This feature can be used in combination with “Include()” and batch querying to maximize the performance of your Marten backed persistence.
  • You can use any tooling you want that’s compatible with Postgresql to poke and prod a Marten-ized database. I just use pgAdmin, but Datagrip or even just Visual Studio is useful.
  • Marten has quite a few more useful diagnostic abilities you can use to analyze the SQL being generated or track database activity by session. In a later blog post, I’ll talk about the reusable recipe we’ve built for Marten integration into FubuMVC applications.

 

Why we’re getting off of RavenDb

I’ve been asked several times since we started working on Marten in public what it would take for us to change our minds and continue with RavenDb. I think it’s quite possible that Voron will make a positive difference, but as I’ll explain a little below, we just don’t trust RavenDb’s quality and software engineering practices.

So why are we wanting to move away from RavenDb?

  • We’ve had multiple day+ outages due to RavenDb indexes getting corrupted and being unable to rebuild. That in a nutshell is more than enough reason to move on.
  • We’ve been concerned for years with RavenDb’s internal quality. We’ve experienced a number of regression bugs when changing versions of RavenDb to the point where we’re unwilling to even try upgrading it.
  • Their release and versioning strategies are not consistent with Semantic Versioning, so you never know if you’re going to get breaking changes in minor or revision level version changes
  • Unresponsive support when we’ve had production issues with RavenDb
  • We’ve not had a lot of success with the DevOps type tooling around RavenDb (replication, etc.) and we’re hopeful that adopting Postgresql helps out on that front.
  • Resource utilization. RavenDb requires a lot of handholding to keep the memory utilization reasonable. Naive usage of RavenDb almost invariably leads to problems.
  • The stale data issue as a result of RavenDb’s eventual consistency strategy has been a major source of friction for us

 

Health Monitoring and Task Reassignment in our Service Bus Applications

FubuMVC 3.0 actually has a full blown service bus framework that started as an add on project called “FubuTransportation.” We’ve used it in production for 3 years, we’re generally happy with it, and it’s the main reason why we’ve done an about face and decided to continue with FubuMVC again.

Corey Kaylor and I have been actively working on FubuMVC again. We’re still planning a reboot of at least the service bus functionality to the CoreCLR with a more efficient architecture next year (“Jasper“), but for right now we’re just working to improve the performance and reliability of our existing service bus applications. The “health monitoring” and persistent task functionality explained here has been in our codebase for a couple years and used a little bit in production, but we’re about to try to use it for something mission critical for the first time. I’d love to have any feedback or suggestions for improvements you might have. All the code shown here is pulled from this namespace in GitHub.

A Distributed System Spread Over Several Nodes

For the sake of both reliability and the potential for horizontal scaling later, we want to be able to deploy multiple instances of our distributed application to different servers (or separate processes on the same box as shown below:

 

BasicApp
A distributed application behind a load balancer

We generally employ hardware load balancers to distribute incoming requests through all the available nodes. So far, all of this is pretty typical and relatively straight forward as long as any node can service any request.

However, what if your architecture includes some kind of stateful “agent” that can, or at least should, be active on only one of the nodes at a time?

I’m hesitant to describe what we’re doing as Agent Oriented Programming, but that’s what I’m drawing on to think through this a little bit.

Agents
“Agent” worker processes should only be running on a single node

In our case, we’re working with a system that is constantly updating a “grid” of information stored in memory and directing work through our call centers. Needless to say, it’s a mission critical process. What we’re attempting to do is to make the active “agent” for that planning grid be managed by FubuMVC’s service bus functionality so that it’s always running on exactly one node in the cluster. That means that we need to be able to:

  • Have the various nodes constantly checking up on each other to make sure that agent is running somewhere and the assigned node is actually up and responsive
  • Be able to initiate the assignment of that agent to a new node if it is not running at all
  • Potentially shut down any extraneous instances of that agent if there is more than one running

Years ago, Chris Patterson of MassTransit fame explained something to me called the Bully Algorithm that can be used for exactly this kind of scenario. With a lot of help from my colleague Ryan Hauert, we came up with the approach described in this post.

 

Persistent Tasks

I reserve the right to change the name later (IAgent maybe?), but for now the key interface for one of these sticky agents is shown below:

public interface IPersistentTask
{
    Uri Subject { get; }

    // This is supposed to be the health check
    // Should throw an exception if anything is wrong;)
    void AssertAvailable();
    void Activate();
    void Deactivate();
    bool IsActive { get; }

    // This method would perform the actual assignment
    Task<ITransportPeer> SelectOwner(IEnumerable<ITransportPeer> peers);
}

Hopefully the interface is largely self descriptive. We were already using Uri’s throughout the rest of the  code, and that made sense to us to use that to identify the persistent tasks. This interface gives developers the hooks to start or stop the task from running, a way to do health checks, and a way to apply whatever kind of custom owner selection algorithm you want.

These persistent tasks are added to a FubuMVC application by registering an instance of this interface into the application container (there is a simple recipe for standalone tasks that deals with both interfaces in one class):

public interface IPersistentTaskSource
{
    // The scheme or protocol from the task Uri's
    string Protocol { get; }

    // Subjects of all the tasks built by this
    // object that should be running
    IEnumerable<Uri> PermanentTasks();

    // Create a task object for the given subject
    IPersistentTask CreateTask(Uri uri);
}

The IPersistentTaskSource might end up going away as unnecessary complexity in favor of just directly registering IPersistentTask’s. It was built with the idea of running, assigning, and monitoring agents per customer/tenant/region/etc. I’ve built a couple systems in the past half decade where it would have been very advantageous to have had that functionality.

The ITransportPeer interface used in the SelectOwner() method models the available nodes and it’s described in the next section.

 

Modeling the Nodes

The available nodes are modeled by the ITransportPeer shown below:

public interface ITransportPeer
{
        // Try to make this node take ownership of a task
	Task<OwnershipStatus> TakeOwnership(Uri subject);

        // Tries to ask the peer what the status is for all
        // of its assigned tasks
	Task<TaskHealthResponse> CheckStatusOfOwnedTasks();

	void RemoveOwnershipFromNode(IEnumerable<Uri> subjects);

	IEnumerable<Uri> CurrentlyOwnedSubjects();

	string NodeId { get; }
	string MachineName { get; }
	Uri ControlChannel { get; }

        // Shutdown a running task
	Task<bool> Deactivate(Uri subject);
}

ITransportPeer’s come in just two flavors:

  1. A class called PersistentTaskController that directly controls and manages the tasks on the executing node.
  2. A class called TransportPeer that represents one of the external nodes. The methods in this version send messages to the control channel of the node represented by the peer object and wait for a matching response. The other nodes will consume those messages and make the right calls on the local PersistentTaskController.

 

Reassigning Tasks

Now that we have a way to hook in tasks and a way to model the available peers, we need some kind of mechanism within IPersistentTask classes to execute the reassignment. Right now, the only thing we’ve built and used so far is a simple algorithm to assign a task based on an order of preference using the OrderedAssignment class shown below:

public class OrderedAssignment
{
	private readonly Uri _subject;
	private readonly ITransportPeer[] _peers;
	private int _index;

	public OrderedAssignment(Uri subject, IEnumerable<ITransportPeer> peers)
	{
		_subject = subject;
		_peers = peers.ToArray();
		_index = 0;
	}

	public async Task<ITransportPeer> SelectOwner()
	{
		return await tryToSelect().ConfigureAwait(false);
	}

	private async Task<ITransportPeer> tryToSelect()
	{
		var transportPeer = _peers[_index++];

		try
		{
			var status = await transportPeer.TakeOwnership(_subject).ConfigureAwait(false);

			if (status == OwnershipStatus.AlreadyOwned || status == OwnershipStatus.OwnershipActivated)
			{
				return transportPeer;
			}
		}
		catch (Exception e)
		{
			Debug.WriteLine(e);
		}

		if (_index >= _peers.Length) return null;

		return await tryToSelect().ConfigureAwait(false);
	}
}

Inside of an IPersistentTask class, the ordered assignment could be used something like this:

public virtual Task<ITransportPeer> SelectOwner(IEnumerable<ITransportPeer> peers)
{
    // it's lame, but just order by the control channel Uri
    var ordered = peers.OrderBy(x => x.ControlChannel.ToString());
    var completion = new OrderedAssignment(Subject, ordered);

    return completion.SelectOwner();
}

 

Health Monitoring via the Bully Algorithm

So now we have a way to model persistent tasks, reassign tasks, and model the connectivity to all the available nodes.

Inside of PersistentTaskController is this method that checks all the known persistent task state on every known running node:

public async Task EnsureTasksHaveOwnership()
{
	// Go run out and check the status of all the tasks that are
	// theoretically running on each node
	var healthChecks = AllPeers().Select(async x =>
	{
		var status = await x.CheckStatusOfOwnedTasks().ConfigureAwait(false);
		return new { Peer = x, Response = status };
	}).ToArray();

	var checks = await Task.WhenAll(healthChecks).ConfigureAwait(false);

	// Determine what corrective steps, if any, should be taken
        // to ensure that every known task is running in just one place
	var planner = new TaskHealthAssignmentPlanner(_permanentTasks);
	foreach (var check in checks)
	{
		planner.Add(check.Peer, check.Response);
	}

	var corrections = planner.ToCorrectionTasks(this);

	await Task.WhenAll(corrections).ConfigureAwait(false);

	_logger.Info(() => "Finished running task health monitoring on node " + NodeId);
}

In combination with the TaskHealthAssignmentPlanner class, this method is able to jumpstart any known tasks that either aren’t running or were running on a node that is no longer reachable or reports that its tasks are in an error state.

The EnsureTasksHaveOwnership() method is called from a system level polling job running in a FubuMVC application. There’s an important little twist on that though. To try to ensure that there’s much less chance of unpredictable behavior from the health monitoring checks running on each node simultaneously, the timing of the polling interval is randomized from this settings class:

public double Interval
{
    get
    {
        // The *first* execution of the health monitoring takes
        // place 100 ms after the app is initialized
        if (_initial)
        {
            _initial = false;
            return 100;
        }
                
        // After the first call, the polling interval is randomized
        // between each call
        return Random.Next(MinSeconds, MaxSeconds) * 1000;
    }
}

I found an article advising you to randomize the intervals somewhere online at the time we were building this two years ago, but I don’t remember where that was:(

By using the bully algorithm, we’re able to effectively make a cluster of related nodes able to check up on each other and start up or reassign any tasks that have gone down. We’re utilizing this first to do a “ready standby” failover of an existing system.

Actually Doing the Health Checks

The health check needs to run some kind of “heartbeat” action implemented through the IPersistentTask.AssertAvailable() method on each persistent task object to ensure that it’s really up and functioning. The following code is taken from PersistentTaskController where it does a health check on each running local task:

public async Task<TaskHealthResponse> CheckStatusOfOwnedTasks()
{
	// Figure out which tasks are running on this node right now
	var subjects = CurrentlyOwnedSubjects().ToArray();

	if (!subjects.Any())
	{
		return TaskHealthResponse.Empty();
	}

	// Check the status of each running task by calling the
	// IPersistentTask.AssertAvailable() method
	var checks = subjects
		.Select(async subject =>
		{
			var status = await CheckStatus(subject).ConfigureAwait(false);
			
			return new PersistentTaskStatus(subject, status);
		})
		.ToArray();

	var statusList = await Task.WhenAll(checks).ConfigureAwait(false);

	return new TaskHealthResponse
	{
		Tasks = statusList.ToArray()
	};
}

public async Task<HealthStatus> CheckStatus(Uri subject)
{
	var agent = _agents[subject];

	return agent == null 
		? HealthStatus.Unknown 
		: await checkStatus(agent).ConfigureAwait(false);
}

private static async Task<HealthStatus> checkStatus(IPersistentTaskAgent agent)
{
	return agent.IsActive
		? await agent.AssertAvailable().ConfigureAwait(false)
		: HealthStatus.Inactive;
}

 

 

Subscription Storage

Another obvious challenge is how does each node “know” about its peers? FubuMVC pulls that off with its “subscription” subsystem. In our case, each node is writing information about itself to a shared persistence store (mostly backed by RavenDb in our ecosystem, but we’re moving that to Marten). The subscription persistence also enables each node to discover its peers.

Once the subscriptions are established, each node can communicate with all of its peers through the control channel addresses in the subscription storage. That basic architecture is shown below with the obligatory boxes and arrows diagram:

Subscriptions

The subscription storage was originally written to enable dynamic message subscriptions between systems, but it’s also enabled our health monitoring strategy shown in this post.

 

 

Control Queue

We need the health monitoring and subscription messages between the various nodes to be fast and reliable. We don’t want the system level messages getting stuck in queues that might be backed up with normal activity. To that end, we finally put the idea of a designated “control channel” into FubuMVC so that you can designate a single channel as the preferred mechanism for sending control messages.

The syntax for making that designation is shown below in a code sample taken from FubuMVC’s integrated testing:

public ServiceRegistry()
{
    // The service bus functionality is "opt in"
    ServiceBus.Enable(true);

    // I explain what "Service" in the next code sample
    Channel(x => x.Service)
        // Listen for incoming messages on this channel
        .ReadIncoming()

        // Designate this channel as preferred for system level messages         
        .UseAsControlChannel()

        // Opts into LightningQueue's non-persistent mode               
        .DeliveryFastWithoutGuarantee(); 

    // I didn't want the health monitoring running on this node
    ServiceBus.HealthMonitoring
        .ScheduledExecution(ScheduledExecution.Disabled);
}

 

If you’re wondering what in the world “x => x.Service” refers to in the code above, that just ties into FubuMVC’s strong typed configuration support (effectively the same concept as the new IOptions configuration in ASP.Net Core, just with less cruft;)). The application described by ServiceRegistry shown above also includes a class that holds configuration items specific to this application:

public class TestBusSettings
{
    public Uri Service { get; set; } = "lq.tcp://localhost:2215/service".ToUri();
    public Uri Website { get; set; } = "lq.tcp://localhost:2216/website".ToUri();
}

The primary transport mechanism we use is LightningQueues (LQ), an OSS library built and maintained by my colleague Corey Kaylor. LQ is normally a “store and forward” queue, but it has a new, opt-in “non persistent” mode (like ZeroMQ, except .Net friendly) that we can exploit for our control channels in FubuMVC. In the case of the control queues, it’s advantageous to not persist those messages anyway.

 

My Concerns

It’s damn complicated and testing was obscenely hard. I’m a little worried about network hiccups causing it to unnecessarily try to reassign tasks. We might put some additional retries into the health checks. The central subscription persistence is a bit of a concern too because that’s a single point of failure.

Quick Twitch Coding with TestDriven.Net

EDIT: There’s a newer version available here.

I started working in earnest with CoreCLR and project.json-enabled projects a couple weeks ago, and by “working” I mean upgrading tools and cleaning out detritus in my /bin folders until I could actually sweet talk my computer into compiling code and running tests. I’ve been very hesitant to jump into the CoreCLR world in no small part because Test Driven Development (TDD) is still my preferred way to write code and I felt like the options for test runners in the CoreCLR ecosystem has temporarily taken a huge step backward from classic .Net in my opinion (not having AppDomain’s in CoreCLR knocked out a lot of the existing testing tools).

Fortunately, there’s a functioning EAP of TestDriven.Net – my long time favorite test runner – that works with xUnit and CoreCLR that dropped a couple weeks ago that I’m already using. You can download the alpha version of TestDriven.Net here.

If you’re not familiar with TestDriven.Net, it’s a very lightweight addon for Visual Studio.Net that allows you to run NUnit/xUnit.Net/Fixie tests through keyboard shortcuts or context menu commands. The test output is just the VS output window, so there’s no performance hit from launching a heavier graphical tool or updating UI. It’s simple and maybe a little crude, but I’ve always been a fan of TestDriven.Net because it supports a keyboard-centric workflow that makes it very easy to quickly transition from writing code to running tests and back again.

One of my pet peeves is working with folks in the main office who constantly give me lectures about why I should be using vim then proceed to use some absurdly clumsy mouse-centric process to trigger unit tests while I try hard to remain patient.

How I Use It

One of the few customizations I do to my Visual Studio.Net setup is to map the TestDriven.Net keyboard shortcuts to the list below. I’m not saying this is the ultimate way to use it, but I’ve done it for years and it’s worked out well for me.

  • CTRL-1: Run test(s). Put the cursor inside a single test, inside a test class outside of a method, or on a namespace declaration and use the keyboard shortcut to immediately build and execute the selected tests
  • CTRL-2: Rerun the last test(s). When I’m doing real TDD my common workflow is to write the next test (or a couple tests), then run the tests once just to make them TestDriven.Net’s active set. After that, I switch to writing the real code, trigger the CTRL-2 shortcut. From there TestDriven.Net will try to save all outstanding files with changes, recompile, and run the previously selected tests. I like this workflow, especially when it takes more than a single attempt to make a test pass, because it’s much faster than finding the right test to run via any kind of mouse-centric process. Warning though, this shortcut will run the test in the debugger if you previously debugged through the unit test the last time.
  • CTRL-3: Rerun the last test(s) in the debugger. Ideally, you really don’t want to spend a lot of time using the debugger, but when you do, it’s really nice to be able to quickly jump into the exact right place.
  • CTRL-4: Rerun the last test(s) in the original context. Say I have to jump into the debugger to figure out why a test is failing. As soon as I make the changes that I expect to fix the issue, I can trigger CTRL-4 to re-run the current test set without the debugger.
  • CTRL-5: Run all tests in the solution. For simpler solutions, I’ve typically found that running tests this way is faster than the corresponding command line tooling — but that advantage seems to have gone away with the new “dotnet test” tooling.

 

Why not auto-test?

I’m actually not a big fan of auto test tools, at least not on any kind of sizable project and test suite. I really liked using Mocha in its watched mode with Growl in my Javascript work, but even that started to break down when the project started getting larger.

My experience is that auto-test mechanisms are too slow a feedback cycle and they don’t allow you to very easily zero in on the subset of the system you’re actually interested in. Plus I’m getting really tired of Mocha tests getting accidentally checked in with temporary “.only()” calls;)

In addition, my opinion is that “dotnet watch test” functionality doesn’t become terribly useful to me until it’s integrated with something like Growl. Even then, I don’t think I would use it on anything but the smallest test suites.

I will admit thought that I’ve never tried out NCrunch and plenty of the folks I interact with like that, so maybe I’ll change my mind on this one later.