Category Archives: Architecture

Glimpse and HTTP Compression

Well its been a while since our last post, during this time we have been heads down and trying to get the next release out. This effort has been using up the majority of our time, but it will be worth the wait and is poised to be our best release yet. If you are interested in the blow-by-blow accounts feel free to subscribe to the Mailing List or track our Commits.

In this release we have been looking to close out the majority of our outstanding issues in GitHub. With this in mind we have gone through and closed out almost all our 80 issues. This has been no easy task and has forced us to look at problems we have been avoiding for a long time.

One of the biggest has been the conflict between Glimpse and sites that have HTTP Compression turned on. For more time than I care to admit, we have been avoiding this as we didn’t have a very good solution for the problem. But finally Nik came up with an innovative way to get around this issues.

As it turns out (and I know this is stating the obvious) you can alter the HTTP payload after it has been compressed. Unfortunately, with the way that Glimpse leveraged a HttpModule to alter response payloads and the way the ASP.NET pipeline works, we can’t guarantee that we would come before the compression would take place. Hence, if ever Glimpse ran after compression it would destroy the response – obviously something that people weren’t happy with.

Given this, we needed a way to ensure that the necessary script tags would be included in the payload before compression takes place. The answer was to create an Html helper (or like concept) that the developer would “manually” put into the sites master page. This helper would render out the required tags and signal the main system not to run its usual logic. Here is an example of how looks:

In MVC applications, simply add the following HTML helper call in your layout file right before the </body> tag:

@Html.GlimpseClient()

You will need to also add @using Glimpse.Mvc.Html to your view or in web.config.

In WebForms applications, you place the following server control before the </body> tag.

You will also need to register the Glimpse control at the top of your page or in web.config.

<%@ Register TagPrefix="glimpse" Namespace="Glimpse.AspNet.Controls" Assembly="Glimpse.AspNet" %>

We realize that this deviates from the usual “it just works” mantra, but unfortunately in this case when you are using Compression, it looks like this is the best solution.

To get this update, you can either wait for the v1 RC2 or checkout the Daily Builds. Let us know how you get on.

Retrospective: Decision to rearchitect

Its now going on a week sense we got the RC release out for v1. So far the response has been extremely positive. Since that time we have been fixing a couple of the bugs and spiking on some new ideas we have had – if you want to see, checkout the branches on github ;). We have also taken the time to step back and reflect on our last release.

As these things go, it was never our intent that the gap between beta and RC would be as long as it was. In an effort to be transparent, this gap has probably slowed down the momentum that we had gained. Some of this was due to Nik and I needing to spend more time with our families, wanting to ensure that we didn’t burn out, international moves and wanting the project to remain fun for us to work on.

Additional, many smart people have questioned the sanity of completely re-architecting your system, but we felt compelled to do so to ensure that project could move forward. Ideally we would have taken a more evolutionary tack here, but being a framework that people build on, as well as a product people use, this made the decision difficult.

The need to do any of this work comes back to the origins of Glimpse and some fundamental decisions we made on day one of the project. The biggest problem we had was the decision to take a dependency on System.Web. Prior to OWIN and self-hosting movement gaining momentum, this would have been a safe decision, but we have had many requests from various interested parties to remove this dependency. Unfortunately, this was not a straight forward task, but by making the change it meant that Glimpse could work in many more situations and be moving in the same direction as the industry trends – we now have the ability to add support for self-hosted WebAPI and frameworks like NancyFX.

Furthermore, the initial development work for Glimpse was done in a period of 5 weeks between the hours of 10pm and 2am in the lead up to Mix11. Even though many of the abstractions have held up over time, given a better eye to where we could go in the future and more time we probably would have made different decisions and taken different routes. Hence abstracting away System.Web represented a great opportunity to set things up moving forward.

In posts to come, we will talk about the various changes on the client and server, and the details of what went into the underlying changes.

Blacklisting and Remove Plugins

In an effort to try and make some of the lesser known features of Glimpse some air time, we thought we would put together a few short posts on how to perform a coupe of tasks that might get you some quick wins.

First in the list is Blacklisting/Remove Plugins. Out of the box Glimpse provides several plugins. Depending on what version of Glimpse you go for (Glimpse
or Glimpse.MVC3) you will have a variety of tabs that serve different purposes.

We are still refining the list of what is useful and what people want to see, but if there is something you don’t want, removing it is quite straight forward. In this case you would simply add a “pluginBlacklist” element to your glimpse config and using the fully qualified name of the plugin, add items to the blacklist:

<glimpse>
      <pluginBlacklist>
            <add plugin="Glimpse.Mvc3.Plugin.MetaData" />
            <add plugin="Glimpse.Mvc3.Plugin.Binders" />
            <add plugin="Foo.Bar.GlimpsePlugins.CurrentUser" />
      </pluginBlacklist>
</glimpse>

*It should be noted that if you wanted to blacklist 3rd party plugins, this is more than possible using the same method, as demonstrated with the Foo.Bar.GlimpsePlugins.CurrentUser line above.

Other cases where you might want to blacklist plugins, is for different environments. Lets say, if in development you want all tabs, but in UAT, you want half of them removed and in PROD you only want tracing, Glimpse can support this. You could have several reasons to do this like reducing payload size, or for security concerns. All you would need to do is blacklist the plugins you don’t need in the config file for each environment.

If should be noted that, if you blacklist a plugin, not only do we not show that tab, but the plugin never gets wired into the life-cycle of the page. Blacklisted plugins add absolutely no overhead and are never instantiated.

Hope that helps and let us know what you think and if we can do anything more in this area.

404 errors fixed! Goodbye /Glimpse/Config, hello /Glimpse.axd

The short version, is that /Glimpse/Config is being deprecated and being replaced with /Glimpse.axd.

The back story is kind of interesting and we thought we would share what we found with you… needless to say we learn’t a lot about Http Modules/Handlers and how it all comes together.

Background
One of the things I loved so much about Glimpse was the /Glimpse/Config URL. To me this approach seemed so clean and simple, and very web 2.0 ish. However, when we went with this approach we failed to realize some of the gotchas that we ran. The approach we took has led to a number of people experiencing 404 errors in a number of different cases.

 

I guess when you first start creating something you fail to realize the full extent that something will be used. Our methodology to date has been to not over-engineer, develop for the known with a close eye on the future and to get working code into peoples hands. Given this philosophy and the way Glimpse came about, its not entirety surprising that we didn’t catch every possible case out there.

Problem 1
Specifically the technique we used to register our HttpModule, and thus implement clean URL’s, was by using DynamicModuleUtility (see more here – DynamicModuleUtility – a great article by K. Scott Allen). When we originally saw this we thought that this would be a simple way of wiring Glimpse up. Even though NuGet supply’s support for web.config transforms, we wanted to limit the amount we changed to as little as possible. DynamicModuleUtility offered config free HttpModule wire up.

At the time when we took this approach, we knew that this feature was only made possible by taking a dependency on the Microsoft.Web.Infrastructure assembly. But months later when we wanted to support Web Forms, this dependency is something that we didn’t take into account. During testing this problem never arose, as all our test environments also had ASP.NET MVC installed. This obviously presented a problem for people using Glimpse who didn’t have ASP.NET MVC installed.

Problem 2
Another issue arose as a side effect of using DynamicModuleUtility (even for some people that where running MVC sites and hence had the Microsoft.Web.Infrastructure assembly), was the missing runAllManagedModulesForAllRequests attribute from their config. As it turns out, the DynamicModuleUtility.RegisterModule() method registers the Glimpse module as a managed module. If the runAllManagedModulesForAllRequests isn’t set to true, then the module doesn’t get called for .js requests, which leads to another possible 404.

This is also true for web forms site, as the .NET 4, the ASP.NET Empty Web Application template does not include this setting in the default web.config, and neither did the older 3.5 templates. Hence, there are likely a lot of WebForms apps out there that don’t have that setting enabled in their web.config files.

There are a couple different ways this could be resolved, but it seems like the simplest would be to add the runAllManagedModulesForAllRequests setting to the web.config.transform file. But this isn’t something that we wanted to force on people. Our other option was to simply remove the .js extension, after all given that we have total control over the URL the .js was only there for the sake of convention.

When we did this we had the unfortunate side effect of being picked up by some people’s authentication process. Most people have rules in place to exclude .css, .js, etc from being process by asp.net/asp.net mvc, but since we removed the extension this brought Glimpse up on their radar and meant that additional rules needed to be added especially for Glimpse which is not what we wanted.

Problem 3
ASP.NET 4 has the concept of extensionless URL request-handlers, however when RTM shipped, they only worked for files ending with a dot, not for files with no extension. There is a knowledge base article and Hotfix: 980368. Needless to say we weren’t aware of this issue when we made the decision to go with extensionless URL’s.

After applying this patch, extensionless URL request-handlers do actually work for requests without extensions. Service Pack 1 for Win7 and 2008 R2 includes this hotfix, and it turns out all the environments we are testing had this hotfix.

There is a good post about this here – How ASP.NET MVC Routing Works and its Impact on the Performance of Static Requests.

Resolution and Final Fix
I am hoping that anyone reading this can sympathize with trying to work through these various issues at once. I’m a fan of Dr. House and there is never more than one thing wrong with someone at once, but as it turns out this is does not hold true with software. Trying to make sure that people who were still reporting 404 issues had the right versions of the code, when some people did and some didn’t… Needless to say it took a little bit, but I think we now have a total and permanent solution!

The finial resolution we have settled on is to dump /Glimpse/Config all together and go with the more traditional /Glimpse.axd. To me this is really disappointing as the /Glimpse/Config address seems far more elegant. But when developing a tool like Glimpse and having a situation where people need to install hotfixes or unusual changes to your config or anything else like this isn’t a good thing. The bar to entry should be as low as possible and in this case it means going with a /Glimpse.axd URL.

This has the advantage that most people already have rules and procedures in place to deal with *.axd’s and its something that people understand. There are also other well established tools such as ELMAH which use this practice, work in almost every case and people are already using. It does mean we will be adding a few more things to your config moving forward, but we since we are doing the exact same thing as ELMAH (from a config transformation perspective) we feel there is already a well established precedence for this.

In the next release of Glimpse /Glimpse/Config will still exist but will inform people of the change and the fact that they should use /Glimpse.axd moving forward.

In addition, we’ve moved away from leveraging DynamicModuleUtility since many users did not have Microsoft.Web.Infrastructure installed on their server.  For users who download Glimpse via NuGet, this has very little impact because we can leverage web.config transforms to register the HttpModule instead.

Please let us know your thoughts and if you have any feedback or thoughts.