Preparation is the key to public speaking.

I Just got back from speaking in Paris and Munich for MongoDBDays. I’ve been to Europe a number of times before. I was in Spain in 1992 and Greece in 2000 for the Olypmics. In addition, I spent a long period of time in Slovakia, Poland, and England travelling with the Book of Hope(now called OneHope) where I met and got to know my wife, who is from California. We really enjoy travelling and we love Europe, so when MongoDB needed a speaker for the two events in Paris and Munich, I jumped all over it and brought my wife, Heather, along for the ride.

I’m an introvert. It happens to be a rather common trait for programmers. However, introversion just means I get energy from being alone. When my friends and family find out I enjoy speaking to large audiences, it is total surprise and they don’t believe me, mostly because they know I like to be alone. Apparently, on people’s list of fears, public speaking is second only to death. I guess I’ve overcome both of those already, so I’m ready to attempt something else. But until then, some insights related to speaking. I’m not an expert, but I’ve done enough public speaking to come up with a recipe that works for me.

  • Prepare.
    • Even if you’ve given your talk a thousand times, run through it again.
    • Time yourself. When you know how much time it takes to get through, you’ll feel free to take sips of water, pause to think about what you are about to say, or take questions from the audience.
    • Know your slides. You shouldn’t need to look at the screen to know what’s next. Knowing what’s next means you can lead your audience into it.
  • Relax.
    • You are the expert. People came to hear you. They attended your session. You know exactly what you want to say and how to say it (and how long it takes to do so). Nothing to be worried about.
    • If you are relaxed, it makes the audience relaxed. Nothing is worse than watching a nervous speaker. Nervousness inevitably leads to forgetting or making a mistake, which just makes you more nervous. And then it all falls apart.
    • If you are relaxed, you appear confident, and confidence breeds acceptance. If you are confident, then the audience will accept that you know what you are talking about. (It also helps to know what you are talking about for those skeptics in the room).
  • Find some humor.
    • No one comes to a conference to be lectured at. They come to enjoy their time and hopefully get something out of the talks.
    • If you can introduce some humor into your talks, your audience will have a better time. People having a good time are awake and paying attention. And people paying attention means they’ll hear what you really want them to hear.

These notes probably aren’t helpful because the hardest one is related to not being nervous. Not being nervous is incredibly difficult if you are a nervous person. I’m a rather laid back person to being with, but I do remember getting nervous when I first started talking. I remember my heart beating quickly and sweating a little. But once I started, talking about things I was passionate about, I remember myself calming down. Hopefully that happens to you, but you won’t know until you try.

These days, now that I’ve realized I’m a pretty good speaker, I really don’t get nervous anymore as long as I’m prepared. Humor comes naturally and is usually unplanned during a presentation. Sometimes people laugh, sometimes they don’t. It doesn’t matter, cause I think I’m funny and they are laughing one way or another, either with me or at me, and either way is fine with me.

For an SSL Client Certificate to get sent with SslStream, the PrivateKey member must be set.

MongoDB is implementing x509 authentication. This is great for enterprises who issue users certificates or for trusted servers communicating over SSL already. When the server adds support, it means all the drivers also need to add support for it. As we already built in Kerberos support, we made the system trivial to add other authentication systems and it took all of about 15 minutes to include x509 support. However, testing it took hours of my time.

Enabling ssl can be completely done via a connection string, but to add in a client certificate for authentication requires some code. 1

var cert = new X509Certificate2("client.pem");

var settings = new MongoClientSettings
{
    Credentials = new[] 
    {
        MongoCredential.CreateMongoX509Credential("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US")
    },
    SslSettings = new SslSettings
    {
        ClientCertificates = new[] { cert },
    },
    UseSsl = true
};

var client = new MongoClient(settings);

As you can see, I had a .pem file. It included both the certificate and the private key, but the client was sending the certificate, even though it’s obvious I included it. Finally I checked the PrivateKey property on the X509Certificate2 instance and it was null. Hmmm. What is wrong with .NET?

I split the pem file into client.crt and client.key with the intention of loading client.crt and then assigning the private key. Apparently, that is non-trivial. In fact, I found no good examples of this. However, a number of people had success on StackOverflow using BouncyCastle, an open-source crypto API (ported from Java I think). I obviously have nothing wrong with this, but how can the .NET framework not support this?

It turns out openssl can create something that .NET does understand that includes both the certificate and the private key in one file and, when loaded, will have the PrivateKey already applied. Running the below openssl command will generate client.pfx. You’ll need to set a password which we’ll use when we construct the X509Certificate2.

openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt

At this point, passing this certificate into the SslStream’s AuthenticateAsClient method will send the certicate along for the ride.

var cert = new X509Certificate2("client.pfx", "mySuperSecretPassword");
  1. The string in the CreateMongoX509Credential is the RFC2253 format for the subject. It can be found using openssl x509 -in client.pem -inform PEM -subject -nameopt RFC2253

Calling Disconnect in the MongoDB .NET Driver is probably the wrong decision.

It’s kinda funny. Developers see something called Disconnect and just assume they should call it when they are done. Maybe that’s reasonable. If so, we made a mistake by including it in the driver. What’s more is that good API design should make it easy to do the right thing and difficult to do the wrong thing.

Imagine a Nancy module:

public class AuthorsModule : NancyModule
{
    public AuthorsModule()
    {
        Get["/"] = _ => 
       	{
       	    var client = new MongoClient(connectionString);
       	    var server = client.GetServer();
       	    server.Connect();
       	    var library = server.GetDatabase("library");
       	    var authors = library.GetCollection("authors");

       	    var allAuthors = authors.FindAll();

       	    ///
       	    server.Disconnect();
       	    ////

       	    return allAuthors.ToList();
        };
    }
}

Believe it or not, we see this type of code a lot (not generally by people using Nancy); lots of code duplication, lack of abstraction. Anyways, as it is, the above will be detrimental to a site’s performance and cause all kinds of errors that are occasionally difficult to diagnose. Disconnect will cause the connection pool to be emptied and all current in flight operations to be cut off. This may not seem that bad until you realize that all clients using the same connection string are sharing a connection pool. Boom! 1

API design is something we work really hard at in building the drivers at MongoDB. Lots of time is spent going over options. When we are adding new features, all of the drivers are generally doing it concurrently, so decisions generally need to be applicable across all the drivers we maintain, from .NET and Java to Ruby and Python to Node.js and Erlang. Obviously, finding commonality in these is sometimes difficult and our over-arching goal is that each driver should provide something idiomatic to the target audience, something that feels natural. So while the code above may feel natural and idiomatic (and perhaps even obvious), it definitely misses on the Principle of Least Astonishment.

We have begun working on the next major revision of the driver. In fact, all the drivers supported by MongoDB are working on their next major revisions. We are all working through similar issues and trying to unify our designs. The .NET driver is going to try to maintain backwards compatibility (we have a great mechanism to do so 2) but there are certain things where I think backwards compatibility may be a problem. Should Disconnect simply be removed? I really can’t think of any good reason for it to exist.

  1. Even Connect is unnecessary, as the driver will connect automatically when the first operation is conducted.

  2. You’ll notice in the code above that we have a client and then a server. We’re going to leave the GetServer() method for backwards compatibility, but we’ll add a new GetDatabase method to MongoClient, allowing us to unify it with the other drivers.

I’ve been meaning to start blogging again for some time. For some reason, I just can’t get into the habit. I love writing and, although I don’t claim to be good at it, it’s something I want to do. Most of my hangups thus far have mostly been around not thinkg I had anything to share. I think a new tact should be taken.

My old blog was on wordpress and was just a pain to format, syntax highlighting, etc… This new one is based on jekyll and is super easy to build, write new posts, and github pages hosts it for me.

As I work on things, day-to-day, I’ll keep notes. Things I struggle with are probably things other people have struggled with. I’ll jot down how I solved the problems, if I did, for them to server as a reminder to me and hopefully a help to others.

Let’s see how this goes.

The code for this step is located on github.

We just finished doing a small refactoring to introduce a ResolutionContext class. This refactoring was necessary to allow us to handle cyclic dependencies. Below is a test that will fail right now with a StackOverflowException because the resolver is going in circles.

public class when_resolving_a_type_with_cyclice_dependencies : ContainerSpecBase
{
    static Exception _ex;

    Because of = () =>
        _ex = Catch.Exception(() => _container.Resolve(typeof(DummyService)));

    It should_throw_an_exception = () =>
        _ex.ShouldNotBeNull();

    private class DummyService
    {
        public DummyService(DepA a)
        { }
    }

    private class DepA
    {
        public DepA(DummyService s)
        { }
    }
}

Technically, a StackOverflowException would get thrown and caught. However, this type of exception is going to take out the whole app and the test runner won’t be able to complete. Regardless, it shouldn’t take a minute to take out the heap and this should fail almost instaneously.

With a slight modification to our ResolutionContext class, we can track whether or not a cycle exists in the resoluation chain and abort early. There are two methods that need to be modified.

public object ResolveDependency(Type type)
{
    var registration = _registrationFinder(type);
    var context = new ResolutionContext(registration, _registrationFinder);
    context.SetParent(this);
    return context.GetInstance();
}

private void SetParent(ResolutionContext parent)
{
    _parent = parent;
    while (parent != null)
    {
        if (ReferenceEquals(Registration, parent.Registration))
            throw new Exception("Cycles found");

        parent = parent._parent;
    }
}

We begin by allowing the ResolutionContext to track it’s parent resolution context. This, as you can see in the SetParent method, will allow us to check each parent and see if we have tried to resolve a given type already. Other than that, nothing special is going on and everything else still works correctly.

At this point, we are at the end of the Building an IoC Container series. I hope you have learned a little more about how the internals of your favorite containers work and, even more so, that there isn’t a lot of magic going on. This is something you can explain to your peers or mentees and hopefully allow the use of IoC to gain an acceptance in area that has once been off-limits because it was a “black-box”. Be sure to leave me a comment if you have any questions or anything else you’d like to have done to our little IoC container.