Scott Hanselman

IronPython and the DLR march on

March 22, 2008 Comment on this post [12] Posted in ASP.NET | ASP.NET MVC | DLR | Python | Ruby | Silverlight
Sponsored By

I've got a number of emails complaining that folks haven't heard much from the DLR (Dynamic Language Runtime) and things like IronPython and IronRuby.

I think it's due to mostly one thing, the fact that the ASP.NET Futures Page still says July 2007. That's one of the reasons I personally fought to have the ASP.NET MVC not use a Date in its name. It just makes things look, ahem, dated.

I'm working to get that page updated, but I just wanted to make sure folks know that there's lots going on around the DLR. I talked to Mahesh on a video call just yesterday.

There's lots going on and here's some collected resources for you:

Once you've had fun with all that, you might look at John's Dynamic Silverlight in ASP.NET MVC article.

Here's John and Jimmy's talk on Dynamic Silverlight at Mix08:

All other goodness is at http://dynamicsilverlight.net/. Enjoy.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

The Weekly Source Code 21 - ASP.NET MVC Preview 2 Source Code

March 22, 2008 Comment on this post [9] Posted in ASP.NET | ASP.NET MVC | Learning .NET | Programming | Source Code
Sponsored By

And so, Dear Reader, I present to you twenty-first in a infinite number of posts of "The Weekly Source Code." I'm doubling up this week, but the ASP.NET MVC Source was released today and I wanted to share more thoughts. I would also encourage you to check out TWSC 17 on Community ASP.NET MVC code.

Read the Comments

When you're reading source, look for words like "TODO," "HACK," "REVIEW," etc, to find parts of the code that the writers are concerned about.

In the SelectBuilder.cs, there's a comment that says:

// TODO: Should these be HTML encoded or HTML attribute encoded? Need to review all helper methods that call this.
string thisText = HttpUtility.HtmlEncode(listData[key].ToString());
string thisValue = HttpUtility.HtmlEncode(key.ToString());

This is an interesting question. He's asking if they should use System.Web.HttpUtility.HtmlAttributeEncode or HtmlEncode. HTML Attribute Encoding encodes <, " and &.

In ViewUserControl.cs we see these:

public virtual void RenderView(ViewContext viewContext) {
// TODO: Remove this hack. Without it, the browser appears to always load cached output
viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this);
containerPage.RenderView(viewContext);
}

This is a tough one also. Chasing caching issues is a huge hassle and consumed at least 10% of my time when I was writing banking software. Even now it feels like there are subtle (and not-so-subtle) differences between IE and Firefox. Seems like Firefox really caches aggressively.

There's a few marked "REVIEW" like:

    // REVIEW: Should we make this public?
internal interface IBuildManager {
object CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType);
ICollection GetReferencedAssemblies();
}

And this one, which is kind of funny. The property IsReusable in an HttpHandler indicates whether or not an instance has state and as such, should not be reused by ASP.NET property. If you write an HttpHandler and it has no state, just a ProcessRequest, you can "reuse" it which should result in a small perf gain.

protected virtual bool IsReusable {
get {
// REVIEW: What's this?
return false;
}
}

Here's one about overloads:

//REVIEW: Should we have an overload that takes Uri?
[SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings",
Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameters as HttpUtility.UrlEncode()")]
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
Justification = "For consistency, all helpers are instance methods.")]
public string Encode(string url) {
return HttpUtility.UrlEncode(url);
}

We've all written comments like these. The trick is to make sure you've included all your key words in Visual Studio so that all your comments will show up in the Task List and can be dealt with before you ship.

Check out SuppressMessage

Microsoft uses CodeAnalysis a lot and you should too. However, sometimes CodeAnalysis offers suggestions that are wrong or not really appropriate and you'll want to suppress those.

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
Justification = "There is already a ViewData property and it has a slightly different meaning.")]
protected internal virtual void SetViewData(object viewData) {
_viewData = viewData;
}

Looking for references to SuppressMessage is a good way to find out where unwavering "purity" analytics fall down and pragmatism should win the day. That said, it never hurts to reevaluate these occasionally as opportunities for refactoring.

The most interesting aspect is the Justification attribute which is actual prose written by the developers. For example, this is the contents of GlobalSuppressions.cs:

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<system.collections.generic.keyvaluepair  `2>)",
Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<system.collections.generic.keyvaluepair `2>[],System.Int32)",
Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<system.collections.generic.keyvaluepair `2>>.IsReadOnly",
Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]

Here's a good example of a justification:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
public static string SubmitImage(this HtmlHelper helper, string htmlName, string imageRelativeUrl) {
return SubmitImage(helper, htmlName, imageRelativeUrl, null);
}

Code analysis is warning that there's a string parameter with the name "Url", but the justification is valid: "The value is not a regular URL since it may contain ~/ ASP.NET-specific characters"

Look to Utils

As I've said before, whenever I start reading code, I look for things marked "Util." These tell us a few things. Things named Util show the "underbelly" of code and point out where things could either be better factored, either in the thing your reading, or in the larger Framework whatever your reading lives in.

In ASP.NET MVC's project there's a Util folder and a Pair.cs file, so let's check it out.

//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------

namespace System.Web.Util {
using System;

// Generic Pair class. Overrides Equals() and GetHashCode(), so it can be used as a dictionary key.
internal sealed class Pair {
private readonly TFirst _first;
private readonly TSecond _second;

public Pair(TFirst first, TSecond second) {
_first = first;
_second = second;
}

public TFirst First {
get {
return _first;
}
}

public TSecond Second {
get {
return _second;
}
}

public override bool Equals(object obj) {
if (obj == this) {
return true;
}

Pair other = obj as Pair;
return (other != null) &&
(((other._first == null) && (_first == null)) ||
((other._first != null) && other._first.Equals(_first))) &&
(((other._second == null) && (_second == null)) ||
((other._second != null) && other._second.Equals(_second)));
}

public override int GetHashCode() {
int a = (_first == null) ? 0 : _first.GetHashCode();
int b = (_second == null) ? 0 : _second.GetHashCode();
return CombineHashCodes(a, b);
}

// Copied from ndp\fx\src\xsp\System\Web\Util\HashCodeCombiner.cs
private static int CombineHashCodes(int h1, int h2) {
return ((h1 << 5) + h1) ^ h2;
}
}
}

This is a simple but clever class that uses generics to make a Pair of any two types. The interesting part is the CombineHashCodes method that takes the hash codes from each object and combines them in a way that makes that pair's hashcode unique enough for use in a Hashtable later.

The Pair class is used to create a combined object inside the TempDataDictionary class like this:

private Pair<Dictionary<string , object>, HashSet<string>> _sessionData;

...where the Key is the actual TempData storage dictionary, and the value is the list of keys that were modified during one request so that they might survive to the next.

There's lot more to learn from reading this code, and it's going to be fun to watch it grow, change and improve!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

ASP.NET MVC Source Code Available

March 21, 2008 Comment on this post [5] Posted in ASP.NET | ASP.NET MVC | Programming | Source Code
Sponsored By

image My boss's boss has blogged about what's been going on this week: The ASP.NET MVC Source is up on CodePlex at http://www.codeplex.com/aspnet.

You can download, read and compile it now.

The goal is to start releasing drops really often. If you're into it, then watch the source code tab, if not, that's cool too, you can wait until it releases later.

You can enter bugs in the issue tracker or complain in the forums and watch the roadmap as it evolves. You can see how to compile it (unzip and build) as well.

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Hanselminutes Podcast 104 - Dave Laribee on ALT.NET

March 21, 2008 Comment on this post [6] Posted in ASP.NET MVC | Learning .NET | Nant | NCover | NUnit | Podcast
Sponsored By

RWS2-Big My one-hundred-and-fourth podcast is up. In this episode I talk to the always thought-provoking David Laribee (blog) who coined the term ALT.NET just last year. It's turned into a Open Spaces Conference and continues to challenge the status quo, reminding .NET developers of the importance of being agile and enabling processes for continuous improvement.

What does it mean to be to be ALT.NET? In short it signifies:

  1. You’re the type of developer who uses what works while keeping an eye out for a better way.
  2. You reach outside the mainstream to adopt the best of any community: Open Source, Agile, Java, Ruby, etc.
  3. You’re not content with the status quo. Things can always be better expressed, more elegant and simple, more mutable, higher quality, etc.
  4. You know tools are great, but they only take you so far. It’s the principles and knowledge that really matter. The best tools are those that embed the knowledge and encourage the principles 

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

If you have trouble downloading, or your download is slow, do try the torrent with µtorrent or another BitTorrent Downloader.

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Check out their UI Suite of controls for ASP.NET. It's very hardcore stuff. One of the things I appreciate about Telerik is their commitment to completeness. For example, they have a page about their Right-to-Left support while some vendors have zero support, or don't bother testing. They also are committed to XHTML compliance and publish their roadmap. It's nice when your controls vendor is very transparent.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Squeezing the most out of IIS7 Media Bit Rate Throttling

March 21, 2008 Comment on this post [5] Posted in HttpHandler | HttpModule | IIS | Podcast
Sponsored By

image ScottGu blogged about the IIS 7.0 Bit Rate Throttling Module being released. Since IIS 7.0 is totally modular (finally!) I think you'll see lots of increasingly useful modules coming out from the team. I know a couple of cool people over there so I get a little insight into what's coming soon.

Since I'm into podcasting some, I started bugging a PM in the IIS team about the Bit Rate stuff in order to dig deeper into what's going on and how I can exploit it. The next step will be to convince Carl, my producer, that we need to get on this stuff.

His Gu-ness has a better description of Bit Rate Throttling that I could write, so here's the meat of it:

Progressive Download Scenario

In a progressive download scenario a client (like Flash or Silverlight) downloads a video directly off of a web-server, and begins playing it once enough video is downloaded for it to play smoothly.

The benefit of using a progressive download approach is that it is super easy to setup on a web-server. Just copy/ftp a video up to a web-server, obtain a URL to it, and you can wire it up to a video client player. It doesn't require any custom web-server configuration, nor require a streaming server to be installed, in order to enable.

The downside of using a progressive video download approach, though, is that web-servers are by default designed to download files as fast as possible.  So when a user clicks to watch a video on your site, your web-server will attempt to transmit it to the client as fast as possible.  This is fine if the user decides to watch the entire video.  But if the user stops watching the content half way through the video (or navigates to a different page), you will have downloaded a bunch of video content that will never be watched.

If the remaining un-watched video content is several megabytes (or even tens of megabytes) in size, you will end up over time spending a lot of money on bandwidth that is not benefiting your business/site at all....

That's the problem this module tries to solve. If you think it's not a problem, talk to me or Carl. It costs a metric buttload to pay for bandwidth of my podcast and it's a harder problem to solve than you think. (Yes, every show has bittorrent as an option, but few Feed Readers use it). A surprising number of folks visit the site and just click on a show and start listening in whatever Media Player they dig.

If someone starts streaming the first 20 seconds of a 45 minute show, decides they don't like it and stops, we may have to pay for the whole 45 minutes as it might already have been downloaded! This is also good for screencasts.

The media throttling stuff looks at the file you're downloading, "bursts" the first chunk to make the "buffering" part of your listening experience as fast as possible, then it throttles the bandwidth from that point on, making sure it doesn't have to buffer again, but still saving bandwidth.

There's some technical details over here that I care about like (emphasis mine) and more technical details here:

"It's also worth noting that the throttler uses a high-performance asyncronous loop to push the data out, without tying up server threads for what can be a very long operation. For responses coming from files (like most large video files), it also does not need to read the content's of the file being sent into memory, instead just instructing http.sys to send portions of the file out to the client at a time.  Because of this, it won't significantly affect your memory usage. While this mechanism is not as efficient as http.sys's own site-wide bandwidth throttling (which cannot be used to do what we are trying to accomplish here), it is pretty much as lean as it can be."

So, I'm going to give this a try on my local machine. I'll start with a recent WMA of the show and put it in a folder under IIS.

image

Notice that this show is a WMA encoded at 32kps (for low-fi/low-bandwidth listeners) and is in http://mymachine/show. I turned on Bit Rate Throttling from the IIS Management Console.

You can set the throttle rate as a percentage of the encoded rate. I'm leaving it as 100%, so that's 100% of 32kbps after the initial burst of 20 seconds.

image

ASIDE: One of the things that is way better in IIS7 than 6 is dealing with permissions and "blocking issues." You know, when you setup a folder, configure the VDir and you get something like "permission denied" then you spend 20 minutes trying to figure out why you can't serve a freaking text file out of a folder? IIS7 has a "Test Settings" dialog like this that just saved me those 20 minutes.

image

Ok, back to business. When I hit this file I get the quick burst, then throttling hits to slow it down to a value above, but close to, the encoded rate.

image

If I try the hi-fi version of the WMA, you can see the bitrate is higher, so the throttling is smart enough to slow the bandwidth but it's always higher than the encoded rate so there's no skipping.

image

Here's what the burst followed by the throttling looks like charted.

image

Remember that this is just a stock IIS Web Server plus this new module, so we're not running Media Services or a Streaming Server or whatever.

Extending Bit Rate Throttling with Custom Code

I thought this was cool and everything, but I immediately brought up the question that some of my users download directly via RSS Readers, while others click the "play now" button and stream. I don't want to throttle the bandwidth for folks who are downloading, just those who stream. However, I'm not running a streaming server (meaning, that everything is over http://, not some mms:// funky port) so I need to differentiate between the two.

I figured there were a couple ways to handle this. I could make different VDirs in IIS mapped to the same files and have BRT (Bit Rate Throttling) turned off on one and on for the other. It'd work, but meh.

Or, I could add Windows-Media-Player/11.0.5721.5145 the end of the URL and turn BRT off for those using a custom coded IIS Module.

How to I write a module? I could make a bin folder and build a DLL, etc, but I could also just make an App_Code folder, apply the appropriate permissions...

image

...and put the source for my custom module in it. I actually wrote it in Notepad.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.IO;

namespace Hanselmodules
{
    public class CustomBRTModule : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.BeginRequest += new EventHandler(OnBeginRequest);
        }

        public void Dispose(){}

        public void OnBeginRequest(Object source, EventArgs e)
        {
            HttpApplication app = (HttpApplication)source;
            HttpContext context = app.Context;

            if (context.Request.QueryString["download"] == "true") //make these fast
            {
                context.Request.ServerVariables.Set("ResponseThrottler-InitialSendSize", "60000");
                context.Request.ServerVariables.Set("ResponseThrottler-Rate", "6000");
            }
        }
    }
}

Basically, I just check for ?download=true on my URL and set my initial send size and rate to really big numbers. (Certainly they could be bigger, come from config, or be calculated by me.)

From the Modules section of the IIS Manager I hit Add Module and my new module shows up. I name it and select it and it appears in the web.config in my /show folder.

 image

After installing this module if I hit: http://mymachine/show/foo.wma I get appropriate throttling, and if I hit http://mymachine/show/foo.wma?download=true I don't. Below you can see screenshots of one download finished at 9megs a second while the other is throttled at 28K/s.

image

Now, this is just one example. I might want to do something cool with JavaScript that appends the ?download if a person clicks a button, or I might want to "sniff" for browser User-Agents versus Media Players like "Windows-Media-Player/11.0.5721.5145" or iTunes/Zune or the like. It's up to me, as writing the IIS7 modules is easy.

You could even use BRT and techniques like this to throttle bandwidth to data (non-media) files, and give different chunks of bandwidth to different levels of users. My module could have checked if it was a paid user and give them preferred download speeds. Pretty sweet. Now, off to talk to Carl! :)

Related Links:

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.