Archive for February, 2010

Wanna Review My Code?

16 commentsWritten on February 23rd, 2010 by
Categories: Off Topic

I just wrote some code, and i’d like your opinion on it.  The thing is, i’m not going to provide any context as to what it does or why certain decisions were made since i know you guys like to be challenged.  You also might want to keep the following in mind when reading it:

  1. it might contain bugs that i’m not aware of
  2. it contains weird parts that were either brainfarts on my part, things i did on purpose to avoid possible issues, or both
  3. it contains at least one bug that i know about, yet don’t care about
  4. i removed the comments that i originally put in it to make things more interesting
  5. i haven’t tested the code yet
  6. i haven’t even executed it yet
  7. i think it’s ok… but i’m not sure

Questions will be answered if you have them (and i’m sure you will) though i can’t make any promises as to how soon i can answer them… I will post a follow-up post to discuss the code in its entirety later on, though i’ll probably wait a few days to do so.

This is the code:

    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();

            }

        }

    }

You’ll Never Get Sustainable Progress For Free

4 commentsWritten on February 21st, 2010 by
Categories: Opinions

Ayende recently wrote about how most software development processes ignore the actual building of software.  Which reminded me of an excellent post written by James Shore over a year ago, and that i commented on as well.  What James (and Ayende) are saying is that if you don’t actually take care of the way you build the software, no process can guarantee that any kind of perceived progress in the beginning can be sustained over the long run.  Sustainable progress takes effort, and you’ll never keep it up if you don’t put the proper practices in place to enable it.

The sad (and typical) part is that the methodology which makes everything sound easy and prescribes the least amount of effort required is the one that took off the most.  Obviously, i’m talking about Scrum.  Scrum makes no mention whatsoever about technical practices that are required to enable sustained progress and Scrum proponents will proudly proclaim that it doesn’t need to since it’s about product development instead of software development.   You can easily become a certified Scrum master while you might not know anything about real-world software development.  In fact, i’ve seen plenty of people boasting that certification on their resume and their linkedin profiles while they really shouldn’t be involved in any kind of professional software development to begin with.

And since Scrum is simple enough for middle-management (you know who i’m talking about… the ones that are usually not competent enough to promote to upper management) to understand, they jump on it as well and before you know it, they’ll be talking about the Scrum concepts as if they actually knew what they’re talking about.  Teams and even entire departments in large corporations are told to be ‘agile’ and follow the Scrum rules and concepts for every new project.  And they do.  And it works great… for a while.  We all know what happens after that.

Then take a look at Extreme Programming (XP).  It’s been around for a while now.  And it unfortunately doesn’t have a good, catchy name.  In fact, its name is probably one of the biggest reasons why it never took off the way Scrum did.  XP prescribes a lot more than Scrum, and even details the technical practices that you’ll need to enable sustainable progress.  And while you don’t need every single one of them, they all provide major benefits and the more of them that you do use, the better off you’ll be.   So what is the problem with XP?  I never really understood why so many people jumped on Scrum, and now Lean (until the Toyota recalls that is) but never really got into XP.   Well yeah i do understand.  XP takes more work and effort to understand and apply.  And that, my friends, is the price you’ll have to pay for sustainable progress(*).

*: i’m talking about the actual effort and work, not XP in itself

Avoiding Memory Leaks With NServiceBus And Your Own Castle Windsor Instance

15 commentsWritten on February 19th, 2010 by
Categories: Castle Windsor, Memory Management, nservicebus

If you’re using NServiceBus together with your own instance of Castle Windsor, there is one thing you really need to look out for.  NServiceBus was originally developed with Spring.NET as its IoC container, but it’s been changed to support multiple containers in a similar manner as Agatha does it.  Agatha however, was originally developed with Castle Windsor as its IoC container, and as such is well aware of Windsor’s need to explicitly release resolved components.   NServiceBus unfortunately was not aware of this need, and a workaround that they have introduced is to set Windsor’s ReleasePolicy to the NoTrackingReleasePolicy (which doesn’t hold any instances in memory, but doesn’t provide any cleanup either) if you configure NServiceBus to use its own instance of Castle Windsor.  However, if you’re integrating NServiceBus into a project that is already using Castle Windsor, then you probably want NServiceBus to use your instance of Castle Windsor.

And that is when problems might appear.  If you’re using Castle Windsor with the default ReleasePolicy (which is the LifecycledComponentsReleasePolicy) then each resolved transient instance will be stored in memory by that policy until the instance is explicitly released.  The benefit of this policy is that the container can automatically dispose any disposable transient dependency of a resolved component.  In my case, i’ve come to rely on that feature to achieve deterministic disposal behavior throughout my code base. 

Now, when you configure NServiceBus and pass it your instance of Castle Windsor, it obviously doesn’t change the ReleasePolicy like it does when it creates its own instance of Castle Windsor.   This is good because changing the policy of a passed in container would almost certainly have a huge behavioral implication for the application and such an action would be unacceptable when integrating a new framework into your project.   But since NServiceBus doesn’t have the notion of needing to release resolved components, every single transient instance it resolves through your container will be stored in memory until the application’s process is terminated.  Which means that you’ll leak instances of the following types for each message that your system needs to handle:

  • NServiceBus.Grid.MessageHandlers.GridInterceptingMessageHandler
  • NServiceBus.Sagas.Impl.SagaMessageHandler
  • Your own MessageHandlers (and their transient dependencies as well)

If your MessageHandlers don’t have dependencies (highly unlikely if you’re already using an IOC container) then you’d still have 3 leaking instances per incoming message.  Add the number of transient dependencies of any handler to that and the number of leaking instances can increase dramatically.

First of all, if you do not depend on Windsor’s default ReleasePolicy’s behavior, then the easiest way to avoid this problem is definitely to set the container’s ReleasePolicy to the NoTrackingReleasePolicy like NServiceBus does itself when it’s configuring itself with a new instance of the container.

If you do depend on it, and you don’t want leaking instances that hang around forever, then the approach listed below is one way to solve this problem.  There are probably other solutions available, and while the approach listed below can definitely be considered to be a HACK, i do think it’s the best solution to this particular problem.

Because we don’t want to change anything about the way that we’re already using the container, we just need to make sure that NServiceBus’ usage of the container doesn’t conflict with ours.  That basically means that we need to make sure that the components that it resolves should not be tracked by the container.   There are 2 kinds of components that NServiceBus will resolve during normal operation:

  1. Its own components that it needs to implement the features it offers you
  2. Your message handlers that you need to handle incoming messages

The first category is easy to exclude from Windsor’s tracking behavior.  We can simply create our own ReleasePolicy which extends the default ReleasePolicy, and make sure that any instances of an NServiceBus-type are no longer tracked by the container:

    public class MyReleasePolicy : Castle.MicroKernel.Releasers.LifecycledComponentsReleasePolicy

    {

        public override void Track(object instance, Castle.MicroKernel.Burden burden)

        {

            if (!instance.GetType().FullName.StartsWith("NServiceBus"))

            {

                base.Track(instance, burden);

            }

        }

    }

 

Then you need to set this release policy somewhere in your application’s startup routine:

            IoC.Container.Kernel.ReleasePolicy = new MyReleasePolicy();

 

(in this case, IoC.Container returns an IWindsorContainer instance)

This will make sure that no instances of NServiceBus-types will ever leak in the container.  But now we still have to deal with our message handlers.  The solution to making sure they are not disposed is not the cleanest out there but hey, it works.  I basically introduced a base class that all my message handlers will need to inherit from, with the following implementation in the Handle method:

    public abstract class MessageHandler<TMessage> : IMessageHandler<TMessage> where TMessage : IMessage

    {

        public void Handle(TMessage message)

        {

            try

            {

                Process(message);

            }

            finally

            {

                // ugly as hell, but we need this until NSB releases its resolved components

                IoC.Container.Release(this);

            }

        }

 

        protected abstract void Process(TMessage message);

    }

 

Uh oh… i just felt a great disturbance in the Force, as if tens of voices suddenly cried out in terror about my direct usage of the IoC container in a component!

Conceptually, this is wrong on many levels.  Then again, this makes sure that the message handlers (and their dependencies) that are resolved by NServiceBus will always be guaranteed to be released by the comtainer.  It might not be nice, but it avoids the memory leak and it doesn’t force me to change my other code.

And once NServiceBus is modified to release the components it resolves (if it’s ever modified that is…) i only need to get rid of my custom policy and the try/finally block.  Unfortunately, my existing message handlers will then all implement the Process method instead of the Handle method but that is quickly fixed with a simple rename-refactoring.

Even though this is a pretty big hack (IMHO), at least its impact on the code is minimal… it will be easy to get rid of once the real problem is solved in NSB, and there are no real downsides to this that i can think of at the moment.

Have You Jumped On The Bandwagon Yet?

17 commentsWritten on February 18th, 2010 by
Categories: Rants

I'm not sure if this is related to the time of the year, but i (and undoubtedly quite a few of you as well if you're honest) am once again getting pretty annoyed with the fact that the blogosphere is once again filled with "you gotta do this or you're just not cool"-kinda posts. The weird part is that the last time i complained about this was pretty much exactly a year ago.

These days, you're an absolute moron if you're still using a relational database. And forget about getting invited to the best parties if you're not developing according to the Command and Query Responsibility Segregation (CQRS) pattern. And if you're not doing Lean then you're really not worth listening to. Oh no wait, talking about Lean isn't hot anymore since the Toyota recalls so we can scratch that off the list, sorry about that one folks.

Now, i'm not saying that the whole NoSQL and CQRS thing is worthless. I actually find them both very interesting. But to all of you who are now pushing these things as if they are the greatest things since sliced bread, i would just like to ask one thing: can we get some more real-world examples? You do use these things in real-world projects before proclaiming that these approaches will fix all (or most) of our current problems, right? You're not just trying to be cool on the internet, are you? Honestly, of all the people that i hear talking about these things lately i only really believe about a handful of them when they say they use these things in real world projects. I'll leave it to you to figure out who the real ones are, and who is just jumping on the bandwagon.

And no, i'm definitely not going to claim that using an RDBMS for every system is the best choice. I complain about databases every day, but i'm not just going to claim that going with a NoSQL database is going to solve all our problems either. I'd actually feel rather silly doing so, unless of course i'd be able to actually back up what i'm saying. Which i haven't really seen happen yet.

The thing is... there simply is no one-size-fits-all approach to software development and it's pretty sad to see that some idiots actually appear to believe that there is. Sometimes an RDBMS makes sense, and sometimes it doesn't. Sometimes MVC makes sense, and sometimes it doesn't. Sometimes DDD makes sense, and sometimes it doesn't. Sometimes CQRS makes sense, and sometimes it doesn't. That goes for every tool, library, architectural style, or whatever other buzzword you can think of. Use what makes sense for what you need, and let's not pretend to be someone or something that you're not, ok?

Can You Come Up With A WHY Comment For This Code?

5 commentsWritten on February 18th, 2010 by
Categories: Memory Management

I just had to write the following code:

    public class MyReleasePolicy : Castle.MicroKernel.Releasers.LifecycledComponentsReleasePolicy

    {

        public override void Track(object instance, Castle.MicroKernel.Burden burden)

        {

            if (!instance.GetType().FullName.StartsWith("NServiceBus"))

            {

                base.Track(instance, burden);

            }

        }

    }

 

and then this:

            IoC.Container.Kernel.ReleasePolicy = new MyReleasePolicy();

 

to make a problem go away.

Can you come up with a WHY comment? (the category of this post is another hint)