Skip to content

Jimmy Bogard
Syndicate content
Strong opinions, weakly held
Updated: 2 hours 44 min ago

Improving the Git Windows experience: Downloads

Wed, 02/01/2012 - 20:22

I love Git. It’s very powerful tool that lets me bend my repository to my will, with commands and features that blow the other source control providers I’ve used out of the water.

However, the tooling just doesn’t do it justice. From the download, installation, integration and CLI experience, it always feels like (in Windows land) that you’re playing in someone else’s back yard.

Over the next few posts, I’m going to compare the experience of using Git with that of Mercurial, who has, in my opinion, lesser features, but a much MUCH better experience.

The Mercurial download experience

Let’s look at searching and downloading the Mercurial client. When I google “Mercurial” or “Mercurial Windows” or “Mercurial Windows Download” or variants, two of the top results are the official Mercurial home page, or the official Windows client, TortoiseHg.

From there, I want to download Mercurial. Both websites offer very clear ways of doing so. The Mercurial site:

image

And the Tortoise Hg site:

image

Two very large “download buttons”. These buttons are interesting in that:

  • They link directly to the file to be downloaded.
  • They both link to the exact same installer
  • They know what OS you’re using, and display the correct installer accordingly

TortoiseHg is the official Hg client for Windows, and includes:

  • The command line interface
  • Windows Explorer integration
  • Visual tools (Workbench etc.)
  • Visual Studio integration
  • Merge tools

It’s a completely out-of-the box client that includes EVERYTHING that you might need to run Mercurial, all in one package, and consistently presented to the end user.

Next, let’s look at the Git download experience.

The Git download experience

When searching for Git downloads, you’re primarily directed to one of two sites – the official Git site, or the official Git tools site for Windows, hosted on Google Code (and also GitHub, curiously enough). The Git site is clean enough:

image

Except I have 3 download links instead of one. Not a big deal most of the time, but already choices are presented to the end user over the Mercurial site. Clicking on the Windows link takes me to this page:

image

Instead of linking me directly to the installer file to download immediately, I’m directed to the downloads page of the Google Code site, where I am presented with yet even more options. There is nothing in this screen that screams “THIS IS THE INSTALLER YOU WANT IGNORE THE OTHERS”. As someone new to Git, how do I know which to choose? Probably the first one, and most people would choose the first one, but presenting choices here is pointless and confusing.

Not to mention, I’m whisked away to a site that has nothing to do with the original Git site. The official Git site didn’t mention “msysgit” but now I’m on the msysgit Google Code site. Even more confusing is that the file has the name “preview” in it, and the installer is labeled as “Beta”. So is the right one or not? I might be inclined to search for the last “good” release and not a beta/preview one.

The Git installer is also less featured than the Mercurial one. The official Git Windows tools include:

  • Windows Explorer integration (very limited)
  • A CLI through the Git Bash or directly in a command prompt
  • Visual tools (OK tools)

However, I typically don’t point folks to the official Git client. Instead, I point them to Git Extensions, a more fully featured toolset that includes:

  • Windows Explorer integration
  • Visual Studio integration
  • Richer visual tools
  • Bundled merge tool
  • Bundled Git installer

This isn’t the official Git Windows client, so you basically have to know it exists to find it. Almost none of the online tutorials recommend it, even though it matches much more closely to what Mercurial provides out of the box.

Improving the Git download experience

In two easy steps:

  • Have the official Windows client be as full featured as the Hg one. Could just start with Git Extensions and go from there.
  • Copy the Mercurial website’s behavior

In short, prefer Simplicity over Choices. Have defaults, and obvious ways to get to the non-defaults.

Categories: Blogs

Multiple messages and transport messages in NServiceBus

Tue, 01/31/2012 - 16:11

Andreas Öhlund posted recently on the concept of the “transport message” in NServiceBus. One of the mistakes I often see (and made myself) was misunderstanding the boundary of the unit of work NServiceBus applies to messages, especially around sending multiple messages.

In many of our systems, we consume flat files from third party integration partners. We take these flat files and deserialize each line of the file into a distinct message, so we first tried to do something like this:

ProcessLineInFileMessage[] messages = ConvertFileToMessages(file);
Bus.Send(messages); // Sends all logical messages in 1 transport message
view raw MultipleMessagesBad.cs This Gist brought to you by GitHub.

The problem we hit was that the unit of work boundary in NServiceBus is around the transport message, not the logical message. In a file of a million lines, that’s a million logical messages bundled together into one single transport message, and one transaction boundary! We had assumed that the overload for sending multiple messages was simply a helper method that encapsulated a “foreach”. Well, no, it doesn’t. All the messages are wrapped in an envelope known as a “transport message”, and it’s the transport message that defines the unit of work boundary (since that’s the physical message sitting in the queue).

Needless to say, we saw database connection timeouts pretty much immediately. Instead, we modified our use of the bus to instead send one logical message per physical transport message, with our friend the “foreach”:

ProcessLineInFileMessage[] messages = ConvertFileToMessages(file);
foreach (var message in messages)    Bus.Send(message); // Send one logical message at a time
view raw MultipleMessagesGood.cs This Gist brought to you by GitHub.

So when would you use the overloads for sending multiple messages? I’m not sure, but I’ll update if I find out!

Categories: Blogs

Speaking at San Diego DNUG tonight

Tue, 01/24/2012 - 19:01

If you’re in the San Diego area tonight, I’ll be giving my talk on domain modeling. Details below:

http://www.sandiegodotnet.com/

I’ve been told that there is free pizza. If not, I might be able score some stale bagels from my hotel’s lobby, but no promises there.

Hope to see you there!

Categories: Blogs

CodeMash 2012 wrap up

Tue, 01/24/2012 - 07:02

This year was my first to attend the bacon debauchery that is CodeMash. I had been suggested to go by pretty much everyone that I’ve met that has gone, and this year I was fortunate enough to be selected as a speaker.

My talk was on “Crafting Wicked Domain Models” that while was not recorded, all the slides and code can be found on my GitHub:

https://github.com/jbogard/presentations

Although that event wasn’t recorded, check out Claudio Lassala’s blog, where he recorded me doing the talk at the Houston Code Camp a couple months before.

A couple of folks came up to me afterwards telling me that they could never code/refactor in front of a Live Studio Audience. But, since the example was straight out of a real project I had lived through, it made going through the code a lot easier.

The questions afterwards were great, too. I always get some discussion around “it’s great and all, but now I have a bunch more classes to deal with”. It’s a fair criticism, and one to keep an eye out for. The way I see it, if the code is more understandable and more representative of real-world concepts, it’s a win. If, however, I’m having a hard time thinking of the names of classes for which I’m building responsibilities around, it’s a bit of a smell that I’m just inventing abstractions.

CodeMash really was a blast. The people were fantastic, the location was great, the food was fantastic, the beer and bacon were plentiful, and as always, the conversations were unforgettable. Hope to see everyone there next year!

Categories: Blogs

The grand No Flash experiment (update)

Wed, 01/18/2012 - 15:56

My dislike of Flash has been well documented, so last month I thought I would try to see what the internet was like without Flash installed, whatsoever. I removed Flash completely from my system, including any Chrome plugin (Chrome has Flash built in).

I’ve never tried to simply go without Flash. I’ve used FlashBlock and AdBlock to block bad Flash, but for the most part, I couldn’t really tell what sites used Flash or not. I wanted to see how far I could go without Flash.

The final answer: not very far at all.

Three sets of websites were difficult or impossible to use:

  • Restaurant websites (who for some reason are determined to make horrible, horrible sites)
  • Video streaming sites (YouTube, Vimeo, and other media outlets)
  • Some food product-related websites

I’d put “musical group website” in the list, but I don’t really visit those much. Sites like Tazo.com, while not a restaurant, rely wholly on Flash for the entire “experience”, offering no options whatsoever for non-Flash browsers (like my iPad and iPhone). The answer of course is not “OMG let’s put Flash on mobile devices!!!1”, but to stop making bad websites.

Other sites surprised me with their use of Flash. For example, GitHub uses Flash to perform its “Copy/Paste” code operations (which I guess is only possible/feasible with Flash). Gmail uses Flash for some more advanced file attachment controls, but at least has a fallback option.

Final verdict? It is not possible (yet) to use the internet without Flash. Which is unfortunate, because the bulk of my “browsing” these days is on the iPad. It’s so, so annoying to have to switch to a desktop to look up a restaurant’s hours. Unfortunate, and totally unnecessary.

Thankfully, Adobe is forcing the hands of web developers somewhat by discontinuing development of their mobile Flash platform. But we can all do our parts to help rid the world of Flash (for bad uses). If I ever run into a totally Flash-dependent website, I write an email to the webmaster, saying I’m a 56-year-old grandmother who can’t use their website on my iPad and that it’s totally ruined my evening.

Categories: Blogs

Formula for project success

Tue, 01/03/2012 - 15:50

In light of recent conversations around ActiveRecord and Rails, I thought it might be important to recognize the factors in a project success, in terms of the code produced:

image

In order for a software project to be successful, two things matter. What you code (the features you choose to develop) and how you code it (what technology you use, how easy it is to change, etc.)

These two constraints balance against each other, and neither is really more important than the other. If you code crap relative to what you need to code, then what you deliver won’t be good. However, it’s also important to recognize what drives what:

image

That is, what ever features/design/scope of what you’re building should drive the architecture/style/technology/patterns of how you code it. Picking the right before the left is putting the cart before the horse. Understand what you’re building, what the vectors of change will be, how large the application will be, how complex in which areas it will be, and let that drive your decisions on what framework/technology/patterns to use.

Once you know HOW to use a technology, the next step is to know WHEN to use that technology, and more importantly, when not to. Clients don’t care about code, but they do care about a bad product. Know what’s important here, and make sure that the code is merely the means (a very important means) to an end.

Categories: Blogs

Duke Nukem, unhappy marriages, and the Anna Karenina principle

Fri, 12/16/2011 - 16:40

One of my favorite recent books I’ve read is the tome on human societies, “Guns, Germs, and Steel: The Fates of Human Societies”. In it, there is a section examining domesticable aminals. The author walks through the observation that although there are 148 big wild terrestrial herbivorous mammals, those that could potentially be domesticated, only 14 animals passed the test to actually become domesticated.

The reasons for failure of those other large mammals harks back to the first line of Anna Karenina:

Happy families are all alike; every unhappy family is unhappy in its own way.

While all 14 domesticated animals had common traits on why they were successful, each species that cannot be domesticated fails the test for some unique, specific reason. For example, zebras evidently have a nasty habit of biting people and not letting go.

Looking at software projects and the rates of failure in the industry, I think that there is a very similar phenomena: Successful projects all have common reasons for success; failed projects each fail in their own unique, spectacular way.

Duke Nukem and unlimited budgets

At a No Fluff Just Stuff conference a couple of years back, the keynote speaker shared a story about a failed project. He joined the project a couple of years into the development, and the team had yet to release anything to production. He went on to detail that he was on the project another year and a half, with no production release in sight, and left the project.

This project was one of those legacy re-writes, given pretty much unlimited budget and resources, in hopes that this would produce the best possible replacement for the existing product. The project had budget, resources, executive backing and visibility, technical leadership, support from domain experts etc. etc. Yet the project was still a colossal failure. Why? It never released!

Looking at the infamous story of Duke Nukem Forever, I get the same impression. Fresh of the success of Duke Nukem 3D, the software team set out to create the best 3D shooter on the market. This would of course take time and budget. Both of which the team had nearly unlimited resources for. But the technology kept changing and improving underneath their feet, like that line from Alice in Wonderland:

It takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!

Clearly something was missing on this project, but it wasn’t anything to do with resources. So what was missing?

Why projects succeed

Instead of looking at the myriad of reasons for why a project could fail (I always go back to the Classic Mistakes from Steve McConnell), how about we look at successful projects and determine what commonalities these have? If we look at the domesticated animals, they all must possess these six common characteristics:

  • Diet
  • Growth Rate
  • Problems of Captive Breeding
  • Nasty Disposition
  • Tendency to Panic
  • Social Structure

That is, if any candidate for domestication fails in one of the above categories, it can’t be domesticated.

So how can we distill the common project mistakes into a set of common characteristics? Since they’re grouped in specific categories, we can trace many of these back to specific root causes:

  • Right people for the project needs
  • Right budget to achieve the project goals
  • Releasing early and often, or a deadline for delivery
  • Constant introspection to improve delivery
  • Alignment between the project sponsor, management, developers and other team members on project’s goals

If these look familiar, it’s because they pretty much make up the iron triangle of software development from Scott Ambler:

Going in to a project, the entire team from executives to developers need to agree on the parameters of the Scope, Resources, and Schedule, and constantly introspect to make sure that the team constantly improves its ability to deliver.

I know I’m probably missing something here, but it seems that all the other project mistakes seem to stem out of a deficiency around:

  • Scope
  • Resources
  • Schedule
  • Alignment
  • Continuous Improvement

A project can succeed despite any of the Classic Mistakes, but lack of any of the above characteristics seems to doom a project to failure.

Categories: Blogs

Is ThreadStatic a leaky abstraction?

Wed, 12/07/2011 - 16:54

Reading Ayende’s post on integrating Rhino Service Bus and RavenDB, one thing that caught my eye was the use of the ThreadStatic attribute to control the lifecycle of a private field:

public class RavenDbMessageModule : IMessageModule{    private readonly IDocumentStore documentStore;
[ThreadStatic]    private static IDocumentSession currentSession;
    public static IDocumentSession CurrentSession    {        get { return currentSession; }    }
    public RavenDbMessageModule(IDocumentStore documentStore)    {        this.documentStore = documentStore;    }
    public void Init(ITransport transport, IServiceBus serviceBus)    {        transport.MessageArrived += TransportOnMessageArrived;        transport.MessageProcessingCompleted += TransportOnMessageProcessingCompleted;    }
    public void Stop(ITransport transport, IServiceBus serviceBus)    {        transport.MessageArrived -= TransportOnMessageArrived;        transport.MessageProcessingCompleted -= TransportOnMessageProcessingCompleted;    }
    private static void TransportOnMessageProcessingCompleted(CurrentMessageInformation currentMessageInformation, Exception exception)    {        if (currentSession != null)        {            if (exception == null)                currentSession.SaveChanges();            currentSession.Dispose();        }        currentSession = null;    }
    private bool TransportOnMessageArrived(CurrentMessageInformation currentMessageInformation)    {        if (currentSession == null)            currentSession = documentStore.OpenSession();        return false;    }}
view raw RavenDbMessageModule.cs This Gist brought to you by GitHub.

One of the things that really bothers me about an implementation like this is that intimate knowledge of the threading model of Rhino Service Bus is required to properly implement an IMessageModule implementation properly. The CurrentSession property is static, yet the IDocumentStore member is an instance field. Why does an implementer of a message module need to be concerned about lifecycle of its dependencies?

I don’t really think it should – lifecycle of a dependency should at most be the responsibility of the dependency itself. Or even better, the responsibility of the container. Dependencies shouldn’t care where they are used, because that knowledge would violate the whole “D” in SOLID.

Instead, I’d much rather see something like FubuMVC behaviors. Here’s one with NHibernate to have a session always part of a request there:

    public class SimpleUnitOfWorkBehaviour : IActionBehavior    {        readonly IFubuRequest _fubuRequest;        readonly ISessionFactory _sessionFactory;        ISession _session;
        public IActionBehavior InnerBehavior { get; set; }
        public SimpleUnitOfWorkBehaviour(ISessionFactory sessionFactory,                                                 IFubuRequest fubuRequest)        {            _sessionFactory = sessionFactory;            _fubuRequest = fubuRequest;        }
view raw FubuUnitOfWork.cs This Gist brought to you by GitHub.

Note that the behavior doesn’t care about the lifecycle of itself. That’s completely managed by the FubuMVC infrastructure, it’s completely unimportant to the implementor. Then when it comes time to actually create a session, it looks like:

        public void Invoke()        {            _fubuRequest.Set(new Lazy<ISession>(() =>                                   _session ?? (_session = CreateTransactionalSession())));
view raw Invoke.cs This Gist brought to you by GitHub.

In the code above, the behavior chain sets a contextual dependency on the IFubuRequest, which, through the magic of child and nested containers, ensures that subsequent behaviors in the execution pipeline have the correct injected ISession from NHibernate. Nowhere in this code do you see any sort of lifecycle management.

The most you see is things like Lazy and in code that uses the dependency, perhaps a lazy Func<T>. But these are only in place because consumers want to direct the scope, not lifecycle.

Lifecycle of dependencies is best served in the framework. Barring that, the container configuration. Consumers and dependencies do not need to change their design to accommodate the lifecycle constraints of the hosted environment. Pushing that into these pieces leaks the abstraction of the hosting environment.

Categories: Blogs

Is ThreadStatic a leaky abstraction?

Wed, 12/07/2011 - 16:54

Reading Ayende’s post on integrating Rhino Service Bus and RavenDB, one thing that caught my eye was the use of the ThreadStatic attribute to control the lifecycle of a private field:

public class RavenDbMessageModule : IMessageModule{    private readonly IDocumentStore documentStore;
[ThreadStatic]    private static IDocumentSession currentSession;
    public static IDocumentSession CurrentSession    {        get { return currentSession; }    }
    public RavenDbMessageModule(IDocumentStore documentStore)    {        this.documentStore = documentStore;    }
    public void Init(ITransport transport, IServiceBus serviceBus)    {        transport.MessageArrived += TransportOnMessageArrived;        transport.MessageProcessingCompleted += TransportOnMessageProcessingCompleted;    }
    public void Stop(ITransport transport, IServiceBus serviceBus)    {        transport.MessageArrived -= TransportOnMessageArrived;        transport.MessageProcessingCompleted -= TransportOnMessageProcessingCompleted;    }
    private static void TransportOnMessageProcessingCompleted(CurrentMessageInformation currentMessageInformation, Exception exception)    {        if (currentSession != null)        {            if (exception == null)                currentSession.SaveChanges();            currentSession.Dispose();        }        currentSession = null;    }
    private bool TransportOnMessageArrived(CurrentMessageInformation currentMessageInformation)    {        if (currentSession == null)            currentSession = documentStore.OpenSession();        return false;    }}
view raw RavenDbMessageModule.cs This Gist brought to you by GitHub.

One of the things that really bothers me about an implementation like this is that intimate knowledge of the threading model of Rhino Service Bus is required to properly implement an IMessageModule implementation properly. The CurrentSession property is static, yet the IDocumentStore member is an instance field. Why does an implementer of a message module need to be concerned about lifecycle of its dependencies?

I don’t really think it should – lifecycle of a dependency should at most be the responsibility of the dependency itself. Or even better, the responsibility of the container. Dependencies shouldn’t care where they are used, because that knowledge would violate the whole “D” in SOLID.

Instead, I’d much rather see something like FubuMVC behaviors. Here’s one with NHibernate to have a session always part of a request there:

    public class SimpleUnitOfWorkBehaviour : IActionBehavior    {        readonly IFubuRequest _fubuRequest;        readonly ISessionFactory _sessionFactory;        ISession _session;
        public IActionBehavior InnerBehavior { get; set; }
        public SimpleUnitOfWorkBehaviour(ISessionFactory sessionFactory,                                                 IFubuRequest fubuRequest)        {            _sessionFactory = sessionFactory;            _fubuRequest = fubuRequest;        }
view raw FubuUnitOfWork.cs This Gist brought to you by GitHub.

Note that the behavior doesn’t care about the lifecycle of itself. That’s completely managed by the FubuMVC infrastructure, it’s completely unimportant to the implementor. Then when it comes time to actually create a session, it looks like:

        public void Invoke()        {            _fubuRequest.Set(new Lazy<ISession>(() =>                                   _session ?? (_session = CreateTransactionalSession())));
view raw Invoke.cs This Gist brought to you by GitHub.

In the code above, the behavior chain sets a contextual dependency on the IFubuRequest, which, through the magic of child and nested containers, ensures that subsequent behaviors in the execution pipeline have the correct injected ISession from NHibernate. Nowhere in this code do you see any sort of lifecycle management.

The most you see is things like Lazy and in code that uses the dependency, perhaps a lazy Func<T>. But these are only in place because consumers want to direct the scope, not lifecycle.

Lifecycle of dependencies is best served in the framework. Barring that, the container configuration. Consumers and dependencies do not need to change their design to accommodate the lifecycle constraints of the hosted environment. Pushing that into these pieces leaks the abstraction of the hosting environment.

Categories: Blogs

A grand experiment

Tue, 12/06/2011 - 16:37

Flash has crashed for the (hopefully) last time. I’m going to run a little experiment. I’m uninstalling Flash and see how much it affects browsing experience for say, one month.

I suspect that most experiences will be fine on Chrome, except for poorly designed websites who force you to browse information through Flash. For legitimate uses of Flash, like video streaming, I don’t really know who does or does not support Flash yet.

I’ll report back in a month with the results. Or less if you really can’t use the web without Flash anymore.

Categories: Blogs

The value of certifications

Wed, 11/30/2011 - 00:37

Reading Davy Brion’s post on Does Certification Have Any Value?, he provides a common answer:

Someone asked which certificate would be the better choice on Twitter today: Microsoft Certified Professional or Certified Scrum Master. My answer was very simple: neither because they’re both utterly worthless.

That’s a very common answer to those looking at the point of view from those taking the exams as a means of proving they’ve learned something. In that light, things like Certified Scrum Master and Microsoft Certified Professional are useless. They don’t provide any indication whatsoever that the person holding the certification is able to actually apply those skills in the real world.

In fact, if someone comes to me using certification as a substitute for examples of experience, it pretty much guarantees that experience will be lacking but bravado will be abundant.

So if you’re wanting to use certifications as a means of learning – don’t, it’s a waste of time. If you’re wanting to use certifications as a means of gaining credibility – you can, but be aware that those that give you credibility because of a certification are likely clueless.

So do certifications hold no value?

No, there is value in some contexts. Clueless or not, sometimes the illusion of credibility from a certification is better than the alternative for some folks. For example, we often meet clients thinking they need Agile advice, but once we start talking to them, it becomes clear that we can help them in other ways.

However, a certification might be a foot-in-the-door to start a conversation that we would otherwise be eliminated. It’s not being disingenuous – it’s recognizing that we have to understand biases and work with them rather than pretend/hope they don’t exist.

Certifications, in some organizations, have currency beyond the illusion of expertise. This could be in the form of currency for promotions, or special deals with vendors (like the Microsoft Partner program was the last time I was involved with it).

Having a certification gets you points that puts you in “Gold” status that gets lower licensing fees. Basically, certification is a coupon for lower prices. It’s a sacrifice employees make for the good of the whole.

Otherwise, yes, don’t waste your time or money. Don’t worry about the worth of the certification, decide if the process of getting certified holds any value.

Categories: Blogs

Dealing with transactions

Mon, 11/28/2011 - 19:05

In the last post on NServiceBus, I got quite a few comments that one way to fix the problem of dealing with non-transactional operations that must happen if some transaction succeeds is to simply move the non-transactional operation after the transactional one, so that I know that the transaction succeeds. If we delay the sending of an email until after the transaction succeeds, our picture now looks like this:

image

The steps are slightly altered so that the Commit happens before Send. If step 2 fails, step 3 never happens. I see a couple of problems with this approach, namely in that it assumes:

  1. I have explicit control over when transactions happen
  2. I want explicit control over when transactions happen

If #1 is true, I have to wonder if #2 is also desirable. In most cases I run into, I don’t want explicit control over transactions. I don’t want to think about them, or mess with them, or deal with them. I want these to just happen without me having to do any work.

I instead like the idea of a unit of work, or at the very least, a concept of required infrastructure for transaction management. Regardless of the host environment I’m working with, WCF, WPF, ASP.NET, NServiceBus etc., my day to day development takes on a picture like this:

image

Day to day, I’m living in the green section. I don’t want to “remember” to create transactions, deal with a pattern of saving, committing, rolling back etc. This should just be taken care of for me, through required infrastructure. One example is in Ayende’s example of the RavenController in MVC:

using System;using System.Web.Mvc;using Raven.Client;using TekPub.Profiler.BackOffice.Tasks;
namespace TekPub.Profiler.BackOffice.Controllers{ public class RavenController : Controller { protected IDocumentSession documentSession;
protected override void OnActionExecuting(ActionExecutingContext filterContext) { documentSession = MvcApplication.DocumentStore.OpenSession(); }
protected override void OnActionExecuted(ActionExecutedContext filterContext) { try { using(documentSession) { if(filterContext.Exception == null) { documentSession.SaveChanges(); TaskExecuter.StartExecuting(); } } } finally { TaskExecuter.Discard(); } } }}
view raw RavenController.cs This Gist brought to you by GitHub.

On every request, a Raven session is opened, and everything saved at the end of the request. All developers have to do to make sure that transactions are used properly is simply inherit from this controller.

With every application framework I look at, one of the first items I put in is the concept of implicit contextual transactions. The scope of what code I’m working with naturally fits inside a transaction, so it’s not something I want to have to worry about.

If I have to remember to call Commit on a transaction every time I introduce new data manipulation code, that’s just something I’m going to forget to do. Instead, transactions and unit of work management should wrap around my normal application code, without me needing to do anything to manage it.

In the next post, I’ll look at various alternatives to messaging for doing something non-transactional like sending emails (or calling web services), and examine the benefits and drawbacks of each approach.

Categories: Blogs

Stop premature email sending with NServiceBus

Tue, 11/22/2011 - 20:53

We use NServiceBus quite a lot to manage integration points where the other side isn’t transactional and we need to “shore up the process” of communicating with external services. One integration point we often don’t think about in terms of an integration point is the sending of an email.

Often times, you’ll see some sort of process that needs to notify someone that the job is complete via email. It’ll look something like:

public void SomeServiceCall()
{
    DoSomeWorkHere();
    CreateSomeObjects();

    SaveToADatabase();

    var message = new MailMessage();
    var client = new SmtpClient();
    client.Send(message);
}

This is all fine and dandy, but the problem comes when something like this is executed inside a transaction. We expect that if the SomeServiceCall method is wrapped in a transaction, that the database save should roll back. But what about that email? It often won’t fail until the transaction commits, which is AFTER the email is sent:

image

In the picture above, we can see that the transaction only involves the database, but we can’t un-send our email.

What we need to do here is decouple the actual sending of an email with the message to indicate an email needs to be sent. Right now, we’re using a synchronous, non-transactional mechanism of sending an email. Instead, we just need to wrap that interaction point with an NServiceBus message:

public void SomeServiceCall()
{
    DoSomeWorkHere();
    CreateSomeObjects();

    SaveToADatabase();

    _bus.Send(new SendEmailMessage());
}

We’re using the NServiceBus bus to send a message that we want to send an email. The nice thing about this picture is that the sending of that NServiceBus message now participates in the transaction:

image

In the case of failure, that message never makes it over to my NServiceBus host. If it does succeed:

image

Then my message is delivered to the SMTP NServiceBus host, which will then interact with the SMTP server.

By decoupling the action of sending an email with the intention through an NServiceBus message, I can make sure that the email isn’t sent unless I successfully complete the transaction.

Another nice benefit here is that I was originally synchronously sending an email. With this architecture, if the SMTP server goes down, it doesn’t affect the ability of My Service to stay up. Instead, the durable messaging of MSMQ and NServiceBus reliability mechanisms ensures that I don’t lose the messages of sending those emails.

Categories: Blogs

When to use NHibernate

Fri, 11/18/2011 - 16:35

Ayende posted some guidance on when to use NHibernate:

If you are using a relational database, and you are going to do writes, you want to use NHibernate.

If all you are doing are reads, you don’t need NHibernate, you can use something like Massive instead, and it would probably be easier. But when you have read & writes on a relational database, NHibernate is going to be a better choice.

That’s pretty much mirroring my experience lately, although I’m starting to have a higher bar for the writes. If your database actually has relationships enforced by constraints on writes, that’s when I feel that NHibernate is useful. Otherwise, we’re starting to use things like Simple.Data, Massive, PetaPoco etc. for reads and writes.

For CRUD kinds of systems, where you don’t really have relationships, it’s much easier to go the Micro-ORM route, where you’re just trying to get from SQL to POCO as quickly and easily as possible.

However, if you do have relationships that you want to model in code, that pretty much immediately starts to require NHibernate. But, if you draw your DDD bounded contexts well, you’ll find you need a lot less Big Bad Frameworks to get things done.

Categories: Blogs

The last vestiges of Hungarian notation

Wed, 11/09/2011 - 16:35

Certain arguments seem to resurface every few years, like whether or not to use a mocking framework, and more recently on Twitter on why .NET still uses Hungarian notation in a few select cases, namely:

  • Interfaces
  • Generic type parameter names

The argument against Hungarian notation in these cases is that it adds nothing to the equation, and is not self-consistent. We don’t prefix Enums with “E”, classes with “C”, structs with “S”, delegates with “D” and so on. Why are these two special?

I’ve seen perfectly valid arguments on both sides on why these two have special rules, and personally, it’s never really bothered me. But for .NET, those arguing that we should ditch Hungarian for these two cases are missing the point.

The train for picking different naming styles for interfaces and generic type parameter names left the station a long, long time ago. That ship has sailed. Picking a different naming convention that goes against years and years of prior art, established conventions and expectations is OK if you’re the only one who’s ever going to look at your code.

If you do decide to ignore a decade of convention, you’re also deciding to irritate and confuse every .NET developer that reads your code when you’re done. Because every time someone else sees that interface without the “I”, the question will always come up on why that decision was made. Unless you’re just a complete sadist, just stick with the convention, please?

Categories: Blogs

Why do TDD?

Tue, 11/01/2011 - 14:47

Because sometimes your test passes the first time you write it. Either you’re done writing any more code, or your understanding of how your code is supposed to work is wrong. Both paths lead to a better spot than without tests. Writing this because a test I wrote passed, exposing a misunderstanding on how a system I’ve worked on for months.

Getting to a failing test is half about characterizing the behavior you want to see in your system, and half about challenging an assumption on whether your system behaves today how you think it behaves. And challenging assumptions through such a cheap mechanism as an automated test is always a good thing.

Categories: Blogs

Async messaging realities

Wed, 10/26/2011 - 15:17

I got a bit of a chuckle from Ayende’s post on time traveling emails. In it, he shows messages in his email inbox received out of order chronologically from when they actually occurred in the real world.

That’s one of the pillars of message-based architectures, that you don’t guarantee when messages arrive, or what order they arrive in. There are a couple of ways we can deal with this, such as the NServiceBus concept of sagas to orchestrate long-running business processes/transactions, where you can keep track of what messages have been received and react accordingly.

One of the difficulties of moving from a synchronous-based message architecture and an async version is that you lose all of these guarantees of synchronous message processing. That’s why it’s not really advisable to view async as a switch to get turned on, since message-based architectures are an architectural approach or style, not an implementation detail. Lots of assumptions get made when you’re writing synchronous code that don’t fly with an async model.

Testing scenarios that involve more than one message getting processed also get more interesting, since testing frameworks are inherently synchronous processes. It’s why you typically see message handlers tested in isolation, rather than a grand end-to-end scenario. Putting a synchronous end-to-end test on an asynchronous process doesn’t really test a production scenario, so its value is at best misleading.

Putting it succinctly – message-based architectures are more than replacing synchronous with async. It’s a mind-shift to a completely different architectural style where your normal rules of engagement are thrown out the window.

Categories: Blogs

The D in DVCS

Fri, 10/14/2011 - 04:58

Just a reminder that the D in DVCS stands for “Distributed”, not “Disconnected” or “Decentralized”. This is a centralized model (from http://progit.org/book):

And this is Distributed:

Note that in the first picture, you’re reliant and dependent on the server for a lot of operations. Note that in the second picture, the only distinguishing feature of the Server is its label. It’s really just an agreement or convention on what the “central” server is. But we can draw all sorts of more interesting pictures, like:

Which is not hard to do at all with Git. The nice thing about the distributed model is that it opens doors to ways of working that simply aren’t possible or feasible with centralized VCS. You can try and work around it, but ultimately the centralized model of VCS is inferior.

It’s not just the “I can work on an airplane” factor (which is nice) or “I can branch and merge like it’s going out of style” effect (which is nice), but the architecture of a distributed model enables patterns and styles of work that can provide a real, measurable impact to a team’s productivity.

DVCS is not the opposite of CVCS, nor is it its complement. It is the next evolutionary step forward, one that no team I’ve encountered has ever chosen to go back on.

Categories: Blogs