So there’s already (at least) three great .Net implementations out there that support RabbitMQ, why create something different? And why not just use MassTransit out of the box instead of forking it? Good and valid questions.
It started a couple of years ago. We had a project in hardcore dev mode and we wanted to use RabbitMQ as the core of our messaging system. NServiceBus was there, but their Rabbit support was still somewhat suspect and not fully integrated. Our take was: Why pay for a commercial product and then use a community add-on for the core implementation? Of course now Rabbit is a fully supported transport, but then it was a different game and I’m still not sure NSB would be worth the money for us.
We then looked at EasyNetQ and in fact we started using it. Let me make it clear that I love this product, but it was missing some things. At the time it was really just getting up to speed and it didn’t support message object-type routing like NServiceBus and MassTransit.
So we went with MassTransit. This worked great for a while (with a few bug fixes) until we really wanted to implement solid Publisher-Confirms. MassTransit had stated they were going to add it, but it had been a while. I put in a pull request with a naive implementation but the guys instead created their own implementation. The problem was that while it was there, it didn’t really work in our scenarios and would have resulted in message loss. I contacted Mike Hadlow (from EasyNetQ) and asked if he’d be open to accepting a pull for real/full message inheritance support (which is still doesn’t support well). Mike said that he would consider it, but didn’t want to risk EasyNetQ getting overly complicated. So I stuck with MassTransit, created a fork and added our own implementation of Publisher-Confirms.
But then there was something else as well: MassTransit started with MSMQ as the transport. Although the transport is mostly abstracted, there was a lot of cruft in the core and configuration that was MSMQ related. So I basically ripped all of that stuff. In addition, it looked like a few different coding styles had been used and there was a pattern of using typical class names for interfaces and then using an “impl” suffix for the actual implementation. ***Brain explosion sound*** I’m not against that but brain just does not compute. I’m used to the standard IWhatever interface naming standard so I updated all of those and tried to make other class names more uniform.
Although we use it actively, I’ve had Burrows on the shelf for a little bit now. But I think I’m getting ready to dive back in re-energized. Frankly we’ve been experiencing some issues under heavy load and it doesn’t really leverage async well (true of both MassTransit and Burrows). In addition, it’s basic message handling approach can lead to thread starvation if your subscribers don’t process messages quickly, which isn’t obvious. But then there’s the balance between performance and safety that must be considered. Hopefully more coming soon, but meanwhile, check out our current implementation: