Tuesday, April 28, 2015

Change Areas folder convention to Plugins in ASP.Net MVC

ASP.Net MVC is mostly about convention. The controllers are inside Controller folder, cshtml files needs to be under views folder, the views are looked up from ActionResult by the action name etc...But whatever conventions are there, all those can be overridden. That is the beauty of MVC framework.

Recently we faced one scenario of overriding convention in one of the MVC projects. It uses MVC Areas to achieve plugin model. We deploy new plugins into the areas folder without recompiling the original framework web application. During one of the demo, there was a suggestion to rename the 'Areas' folder to 'Plugins' for better naming convention and readability. We tried to resist it as it adds unwanted code. But due to the pressure from leadership we decided to change it. It is good in one way that, we gets more chances to look inside the MVC framework.

Initially thought of having custom controller or ViewEngine. But after playing with MVC for some time, it became very easy as adding some lookup folder paths into RazorViewEngine. Files and folder hierarchy under the Plugins folder needs to be done manually. Right click and add area will not put new files into Plugins folder. Code below. The sub folder structure and files can be organized in side the Plugins folder in the same way how its seen in Area's folder.


        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AddPluginsFolderToAreaLocationFormatsOfRazorViewEngine();
        }

        private static void AddPluginsFolderToAreaLocationFormatsOfRazorViewEngine()
        {
            string[] PluginsLocationFormats = new string
                [] { "~/Plugins/{2}/Views/{1}/{0}.cshtml" };
            var razorEngine = ViewEngines.Engines.OfType<RazorViewEngine>().First();
            razorEngine.AreaMasterLocationFormats = 
                razorEngine.AreaMasterLocationFormats.Concat(PluginsLocationFormats).ToArray();
            razorEngine.AreaViewLocationFormats = 
                razorEngine.AreaViewLocationFormats.Concat(PluginsLocationFormats).ToArray();
        }


If anybody faces issues in getting this run, comment here. I can upload a sample MVC5 project.

http://theshravan.net/blog/configure-the-views-search-locations-in-asp-net-mvc/
http://stackoverflow.com/questions/632964/can-i-specify-a-custom-location-to-search-for-views-in-asp-net-mvc

Tuesday, April 21, 2015

Determining health of system in distributed queueing system to dequeue next message

Recently we are in to the business of building a distributed system where the long running operations to be offloaded to processing machines. Processing machines are pulling the messages from the queue instead of having a manager allocating tasks. 

Initially we were assigning throttling numbers to each of the processing machines according to their configuration such as number of processors, RAM etc...But soon we could see that the machines are either not utilized or over utilized. So decided to introduce a mechanism where the real time machine load needs to considered before taking new message from the queue.

We considered some techniques for sensing the load but those were not feeling better than analyzing the Windows performance counters. So decided to go with looking at the appropriate performance counters before dequeue a new message from the queue.

What are the appropriate performance counters? Its always debatable. We are in the initial stages of the implementation. Hopefully can update soon.

Another challenge we faced was how the performance counter data is translated to a boolean value saying system is healthy or not. We evaluated PAL which reads the .blg files and produces report. But finally reached to a conclusion of saving the performance counter values into database and running own rule engine there which replaces PAL.

Some links on how to work with performance counters from perfmon.exe below

https://technet.microsoft.com/en-us/library/cc722414.aspx
http://www.windowsnetworking.com/articles-tutorials/netgeneral/Scripted-Networt-Defense-Part2.html