Archive for March, 2010

Everybody Wins In The Certification Game

10 commentsWritten on March 20th, 2010 by
Categories: Opinions

You often hear developers complain about the value of certifications.  Most certifications are worthless in my opinion, and you sure as hell don’t need to be smart or talented to be able to get certified.  The only thing you really need is time. That’s it.  So i can understand why so many people in this industry are frustrated with people who are either too hung up on their certifications, or the companies and/or customers who value them so greatly.  But fear not, my friends, for the truth is that we can all benefit from the software certification game.

If you’re a company or an individual who’s looking for an easy way to make a few extra bucks, just create your own certification! The only reason certifications exist is to make more money and there is no reason in the world why you wouldn’t be able to do the same.  Want some proof?  People are paying money to go to a 2 day course which ends with them being proclaimed Certified Scrum Master.  Obviously, most people who’ve actually given it some thought know that it’s a pretty meaningless certificate but hey, plenty of people are willing to pay for it, so why not take advantage?

Suppose you’re a developer who’s primarily interested in getting a nice cushy job for some company where it’s easy to get away with incompetence or an actual lack of demonstrable progress.  The best possible thing for you to do is to get yourself a couple of buzzword-laden certifications, apply with some big companies who’s core business is not software development and that’s it.  You’re pretty much set for life if you want to.

Suppose you’re a developer who’s primarily interested in interesting work.  Simply stay away from every job that lists one or more certifications in its requirement, or even hints that certification might improve your chances of being hired.  Ignoring those kind of jobs probably improves your chances of interesting work by a significant amount and as a bonus, you relieve yourself of the pain of having to deal with people who value certifications.

If you’re a company who’s looking to hire somebody or some other company to develop some software for you, while you have absolutely no idea where you should go, what to look for, and simply don’t want to get fired, then just hire the company that can show you the highest number of certifications.  The software that will be delivered might suck or it might not.  But one thing is for sure: you will not get fired if the software turns out to be a mess.  After all, you hired certified professionals so surely, you can’t be blamed for this fiasco.

As you can see, the certification game really does provide plenty of positive opportunities for a variety of people and interests.  The only people who don’t benefit from the certification game at all, are end users and consumers.  But then again, this industry has a very strong history of not caring about them anyway, so that’s not really a problem we should care about, right?

MSDTC Woes With NServiceBus And NHibernate

19 commentsWritten on March 19th, 2010 by
Categories: .NET bugs, MSDTC, NHibernate, nservicebus

I’ve spent about 3 days trying to get something working that should’ve just worked.  I basically wanted some .NET code to use a distributed transaction to update some data in a database, and then publish a message on the service bus.  I want to do this in a distributed transaction because if something goes wrong, i want to roll back both transactions (the database change and the published message).  Normally, this should just work if you have MS DTC configured correctly.  On my machine, i enabled Network DTC Access, and allowed outbound transaction communication.  On the database server, Network DTC Access was already enabled and both outbound and inbound communication was allowed. 

Now the thing is, i’d either expect DTC to fail outright or to just work.  But it shouldn’t fail in one situation, and work in another.  On my machine, it failed in the following situation (which i’ll further refer to as Situation A):

  1. open a transaction scope
  2. open an nhibernate session
  3. hit the db
  4. publish a message through nservicebus
  5. close the nhibernate session
  6. complete and close the transaction scope

Step 4 and 5 could be switched around but it didn’t make a difference.  In Situation A, i always got a TransactionManagerCommunicationException with the following message:

Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.

Everyone who’s worked with MSDTC before probably knows that exception since it usually takes some fiddling with the settings to make things work.  The thing is, i was pretty sure that my settings, as well as the ones on the database server were correct.  Unfortunately, DTCPing didn’t confirm that since that too failed.

However, i also tried the following sequence of events (Situation B):

  1. open a transaction scope
  2. open an nhibernate session
  3. publish a message
  4. hit the db
  5. close the nhibernate session
  6. complete and close the transaction scope

And guess what.  That actually worked.  With full DTC transaction semantics.  The DTC statistics on the server confirmed that it was indeed using a DTC transaction, and if i made the code fail with an exception both the database action and the published message were correctly rolled back.

So the question is: why on earth does it only work when i publish a message before i hit the db?

During my investigation i noticed that in Situation A, the internal transaction that the transaction scope was using was a SqlDelegatedTransaction.  Which, if i’m not mistaken is an LTM transaction.  When trying to send a message to a message queue, the transaction manager tries to promote the current transaction to an OletxCommittableTransaction since the OleTx transaction protocol is required when using MSMQ (it doesn’t support LTM transactions).  For some reason, promoting the SqlDelegatedTransaction to a full DTC (OleTx) transaction fails on my machine.

In Situation B, the internal transaction is promoted to an OletxCommittableTransaction as soon as you try to send the message to a message queue.  Once it’s time to hit the DB, NHibernate nicely works together with the OletxCommittableTransaction and everything just works.

Now, i have no idea on earth why promotion of a SqlDelegatedTransaction fails, but after a long number of attempts and experiments to get it working correctly, i sorta gave up and figured i’d have to resort to a hack.  What i basically needed was for the transaction scope’s internal transaction to automatically be promoted to an OletxCommittableTransaction before i’d hit the database and without having to publish a dummy message at the beginning of the transaction.

I found one way of doing this which, while being a huge hack, is still relatively clean i think.  I wrote the following class:

    public class DummyEnlistmentNotification : IEnlistmentNotification

    {

        public static readonly Guid Id = new Guid("E2D35055-4187-4ff5-82A1-F1F161A008D0");

 

        public void Prepare(PreparingEnlistment preparingEnlistment)

        {

            preparingEnlistment.Prepared();

        }

 

        public void Commit(Enlistment enlistment)

        {

            enlistment.Done();

        }

 

        public void Rollback(Enlistment enlistment)

        {

            enlistment.Done();

        }

 

        public void InDoubt(Enlistment enlistment)

        {

            enlistment.Done();

        }

    }

 

Then, right after opening the transaction scope and before doing anything else, i do this:

    Transaction.Current.EnlistDurable(DummyEnlistmentNotification.Id, new DummyEnlistmentNotification(), EnlistmentOptions.None);

 

This basically tells the System.Transactions infrastructure that we’re adding our own Resource Manager to the current transaction.  And because it’s a durable Resource Manager, it now automatically promotes the internal transaction to an OletxCommittableTransaction and everything just works.  While our Resource Manager participates in the 2-phase-commit process, it doesn’t actually do anything.  It’s sole purpose is to force the creation of an OletxCommittableTransaction.

Like i said, it’s a hack but it’s still relatively clean.  I still have no idea why i needed to resort to this hack though… If anyone can shed some light on this, i’d highly appreciate it :)

Also, if you ever want to learn more about transactions in .NET or distributed transactions in particular, you really need to check out this article.  Without it, i probably wouldn’t have figured out what to do :)

If Only There Were More Hours In A Day

1 Comment »Written on March 17th, 2010 by
Categories: About The Blog

Some of you who've been reading for a while are probably wondering: "what's with the low frequency of posts lately?"

Well, i'm sort of busy right now... I've got some personal stuff going on, some interesting non-IT related stuff, and the little time i currently have left besides that is spent trying to catch up with a lack of sleep. Things should probably be back to normal in about a week or two though. Until then, i just wanna throw some teaser-blog-post-titles out there that should make their way to this blog soon:

  • Red/Green/Refactor... Well, Not Really
  • How I Currently Feel About Automated Testing
  • Got Memory?!
  • If You Can't Say Anything Bad About It, You Don't Know It Well Enough
  • Don't Touch Production Data
  • Isolation At Work Isn't Necessarily Bad

I'm actually looking forward to them myself :p

The Biggest Logging Anti-Pattern

4 commentsWritten on March 16th, 2010 by
Categories: Rants

shitty_log

Using Copy-On-Write In Multithreaded Code To Reduce Locking Overhead

5 commentsWritten on March 8th, 2010 by
Categories: Multithreading, Performance

I recently posted some code that i asked you to review.  When i posted it, the code had never even executed (that’s right, not even through a test) and i only thought it would do what i needed it to do.  I consider the actual implementation non-obvious (at least for those who don’t know the copy-on-write approach to avoid traditional locking) so i just wanted to hear some reactions to the code from people who didn’t knew the context.  I promised to do a follow-up post to discuss the code in its entirety so here it is.

First, i’ll show the whole class again:

    public class TenantSessionFactoryManager : ITenantSessionFactoryManager

    {

        private readonly ITenantContext tenantContext;

        private readonly ITenantInfoHolder tenantInfoHolder;

        private readonly string mappingAssemblyName;

 

        private readonly object writeLock = new object();

        private Dictionary<Guid, ISessionFactory> sessionFactories;

 

        public TenantSessionFactoryManager(ITenantContext tenantContext, ITenantInfoHolder tenantInfoHolder, string mappingAssemblyName)

        {

            this.tenantContext = tenantContext;

            this.tenantInfoHolder = tenantInfoHolder;

            this.mappingAssemblyName = mappingAssemblyName;

            sessionFactories = new Dictionary<Guid, ISessionFactory>();

        }

 

        public ISession CreateSessionForCurrentTenant()

        {

            var tenantId = tenantContext.CurrentTenantId;

 

            if (!sessionFactories.ContainsKey(tenantId))

            {

                CreateSessionFactoryForCurrentTenant();

            }

 

            return sessionFactories[tenantId].OpenSession();

        }

 

        private void CreateSessionFactoryForCurrentTenant()

        {

            lock (writeLock)

            {

                var tenantId = tenantContext.CurrentTenantId;

 

                if (!sessionFactories.ContainsKey(tenantId))

                {

                    var connectionString = tenantInfoHolder.GetDatabaseConnectionString(tenantId);

 

                    var sessionFactory = new Configuration()

                        .Configure()

                        .AddProperties(new Dictionary<string, string>

                                {

                                    { "connection.connection_string", connectionString },

                                    { "cache.region_prefix", "Tenant_" + tenantId }

                                })

                        .AddAssembly(mappingAssemblyName)

                        .BuildSessionFactory();

 

                    var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);

                    newDictionary[tenantId] = sessionFactory;

                    sessionFactories = newDictionary;

                }

            }

        }

 

        public void RemoveSessionFactoryForTenant(Guid tenantId)

        {

            if (!sessionFactories.ContainsKey(tenantId))

            {

                return;

            }

 

            lock (writeLock)

            {

                if (!sessionFactories.ContainsKey(tenantId))

                {

                    return;

                }

 

                var sessionFactory = sessionFactories[tenantId];

                var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);

                newDictionary.Remove(tenantId);

                sessionFactories = newDictionary;

 

                sessionFactory.Dispose();

            }

        }

    }

 

Basically, the purpose of this class is to hold a set of ISessionFactory instances, each of which belongs to a particular tenant in a multi-tenant application.  Tenants can be added on the fly (without restarting the application) and when an ISessionFactory doesn’t exist yet for a particular tenant, it must be created when the first request for an ISession for that tenant comes in.  Obviously, access to the sessionFactories dictionary must be thread-safe since multiple threads will be reading from the dictionary as well as occasionally writing to it.

I considered 3 options to make sure access to the dictionary would be thread-safe:

  1. Traditional locking (through the lock statement or the Monitor class)
  2. Using the ReadWriterLockSlim class
  3. Using the copy-on-write pattern

Traditional locking was quickly scratched from the list because that would require me to lock for every read of the dictionary as well as every write.  Now, pretty much every single request requires an NHibernate session which means that pretty much every single request results in a lookup in the sessionFactories dictionary.  If i need to lock for every read, this significantly hurts overall throughput of the system. 

The ReadWriterLockSlim might be a good solution here… after all, the short description of this class in MSDN says this:

Represents a lock that is used to manage access to a resource, allowing multiple threads for reading or exclusive access for writing.

Sounds like what i need, right?  But the thing is, i’ve never used the ReadWriterLockSlim class before and it hasn’t really gained my trust yet.  I know that’s a terrible excuse for not using it, but here me out.  While the ReadWriterLockSlim likely reduces locking overhead over traditional locking substantially, there still has to be some overhead for read operations, even if it is small.  In most situations, that small overhead wouldn’t bother me but in this case, that little overhead would be added to pretty much every single request in the system.  Now, writing to a dictionary implies that a new tenant has been added to the system.  In the context of this system, that’s not even gonna happen on a daily basis.  Hell, once a week is probably a best-case estimation and even that is highly optimistic.  So i really don’t want any kind of overhead on read operations when the write operation is only going to happen very occasionally.

That leaves the copy-on-write pattern.  I’ve used it before with success (though at the time, i didn’t know it was a known pattern) so this approach has already gained my trust.  It basically implies that we don’t do any locking on the read operations, but whenever a write operation occurs we copy the original set of objects, perform the write on the newly copied set and then set the reference of the original set to the newly created and modified instance.  During this whole time, every single read is safe.  Successive reads within the same logical operation however aren’t, so the following code would not be thread-safe:

            if (sessionFactories.ContainsKey(tenantId))

            {

                return sessionFactories[tenantId].OpenSession();

            }

 

Because there’s no locking on the reads, the code within the if-block could fail because the sessionFactories reference could be pointing to a new dictionary which no longer contains the element for that key. 

Of course, if you have frequent writes, the overhead of copying the set of objects every time you need to add/remove one might be bigger than you want, so this isn’t a pattern that you should use whenever you need to protect access to a shared resource. For this situation however, i think it’s ideal… though i’d obviously like to hear about better solutions :)

Now, let’s take a closer look at the pieces of code that perform the write operations.  First, adding a new ISessionFactory to the dictionary:

        private void CreateSessionFactoryForCurrentTenant()

        {

            lock (writeLock)

            {

                var tenantId = tenantContext.CurrentTenantId;

 

                if (!sessionFactories.ContainsKey(tenantId))

                {

                    var connectionString = tenantInfoHolder.GetDatabaseConnectionString(tenantId);

 

                    var sessionFactory = new Configuration()

                        .Configure()

                        .AddProperties(new Dictionary<string, string>

                                {

                                    { "connection.connection_string", connectionString },

                                    { "cache.region_prefix", "Tenant_" + tenantId }

                                })

                        .AddAssembly(mappingAssemblyName)

                        .BuildSessionFactory();

 

                    var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);

                    newDictionary[tenantId] = sessionFactory;

                    sessionFactories = newDictionary;

                }

            }

        }

 

As you can see, the entire operation is put between a lock on the writeLock object instance.  The downside of this is that creating an ISessionFactory instance is an expensive operation, which means the lock will be held for a long time (could easily be one or more seconds).  Then again, i don’t anticipate this happening frequently so it’s not that big of an issue… especially since reads aren’t being blocked by this anyway.  This approach also prevents the creation of 2 ISessionFactory instances for the same tenant.  Well, unless i missed a bug here :p

Now, once the ISessionFactory instance is created, we create a new Dictionary based on the contents of the old one and then we add the new ISessionFactory instance to it.  After that, we replace the sessionFactories references with the new dictionary and from that point on, every read will use the new dictionary instance.  During this entire operation, no read operation was impacted negatively. 

Now lets take a look at the other write operation, removing an ISessionFactory instance from the dictionary:

        public void RemoveSessionFactoryForTenant(Guid tenantId)

        {

            if (!sessionFactories.ContainsKey(tenantId))

            {

                return;

            }

 

            lock (writeLock)

            {

                if (!sessionFactories.ContainsKey(tenantId))

                {

                    return;

                }

 

                var sessionFactory = sessionFactories[tenantId];

                var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);

                newDictionary.Remove(tenantId);

                sessionFactories = newDictionary;

 

                sessionFactory.Dispose();

            }

 

The first if-check, which happens outside of the lock is a bug that i missed but that was pointed out in the comments of the original post.  If CreateSessionFactoryForCurrentTenant and RemoveSessionFactoryForTenant would execute concurrently for the same tenant, it’s possible that the ISessionFactory instance of that tenant is never removed from the dictionary (and also never disposed of…) since the check happens outside of the lock and could be executed before the ISessionFactory of the tenant was added to the dictionary.  In that case, the ISessionFactory instance would stay in the dictionary as long as the application stays up.  This is definitely a race condition that you want to avoid in every other situation though in this case, the odds that we’re simultaneously adding and removing the same tenant are slim to none.  Nevertheless, i don’t want to be accused of promoting race conditions so we’ll make the change anyway :)

        public void RemoveSessionFactoryForTenant(Guid tenantId)

        {

            lock (writeLock)

            {

                if (!sessionFactories.ContainsKey(tenantId))

                {

                    return;

                }

 

                var sessionFactory = sessionFactories[tenantId];

                var newDictionary = new Dictionary<Guid, ISessionFactory>(sessionFactories);

                newDictionary.Remove(tenantId);

                sessionFactories = newDictionary;

 

                sessionFactory.Dispose();

            }

        }

 

Now, as you can see we once again create a new dictionary based on the previous one, then remove the ISessionFactory instance for the current tenant and then we overwrite the sessionFactories instance once again.

Finally, there’s the read operation that i specifically didn’t want suffering from locking overhead:

        public ISession CreateSessionForCurrentTenant()

        {

            var tenantId = tenantContext.CurrentTenantId;

 

            if (!sessionFactories.ContainsKey(tenantId))

            {

                CreateSessionFactoryForCurrentTenant();

            }

 

            return sessionFactories[tenantId].OpenSession();

        }

 

The only time this code will block is when a new ISessionFactory for the current tenant needs to be created.  Luckily, that only happens once for each tenant.  As i mentioned earlier in the post, using this pattern doesn’t guarantee that successive reads within the same logical operation are thread safe, so there is a bug in here.  If a tenant already has an ISessionFactory instance, it’s possible that the RemoveSessionFactoryForTenant method has been executed between the if-check and accessing the ISessionFactory based on the tenantId.  In that particular scenario, the ISessionFactory instance is no longer in the dictionary which will cause this code to throw an exception.

That’s a bug that i don’t feel like fixing though… Once a tenant has been removed, they are no longer a paying customer.  If they are no longer paying for the software, there is no reason whatsoever why i should care about any possible exceptions they could get while running the software :)

Seriously though, if the RemoveSessionFactoryForTenant method is called, users of that tenant won’t even have access to the system anymore so it’s really a non-issue.

Anyways, i think i’ve covered the implementation in more detail than you probably cared for.  So, any thoughts? Are there still issues that i haven’t thought of? Is there another approach that you would use for this specific scenario?