September 2004 - Posts

Scalability Is Passé

Five years ago, everyone working server-side was obsessed with building scalable software. Some said we could never be scalable with Microsoft technologies.

Fast forward to 2004. Everyone is obsessed with building “secure” software. Some say we can never be secure with Microsoft technologies.

If we look at what has happened over the last five years, perhaps we can see what might happen in the next five.

1) For scalability, expectations have leveled. In 1999 everyone believed they were building the next eBay and Amazon. Today, nobody is over-hyping the ability to go from 0 to huge overnight. I don’t foresee the same leveling off of expectations for secure software. If anything, the expectation is just starting to grow.

2) Security, interoperability, and flexibility have pushed scalability off the radar screen. On Aaron Skonnard's list, scalability is not even in the top 5 qualities to look for in enterprise software. Most shops with limited resources have to carefully select the qualities to focus on - we can’t have it all. Looking ahead, security and interoperability are here to stay for the next five years.

3) Scalability is easier today because of the platform and runtime. We moved from building web pages with loosely-typed interpreted pages to strongly-typed compiled pages. In some ways, the underlying platform lost features that were abused (think of ADO and server side cursors). Security in the next five years has to get easier too. It is currently hard to run as a non-admin. It is currently hard to run assemblies without full-trust. The platform and runtime can get better in this area, but not make them completely painless.

4) Scalability is easier because of the tools. It’s easy to set performance benchmarks and measure scalability with software. It’s easy to catch possible bottlenecks with syntactic analysis of an application: a cursor declaration in a SQL query, a static constructor in a class. Many security problems require the tougher task of semantic analysis. Where is the application saving a plaintext password? Is this string concatenation putting user input into a SQL string? These will be tough problems to uncover. Additional expertise and heuristics will need to exist in security tools.

5) Scalability education has been constant over the last five years. Follow some guidelines and work with the framework instead of against it, and you’ll have a decently scalable system. Don’t write your own connection pooling and thread pooling libraries – chances are the ones in place will work for 95% of the applications being developed. Security education, on the other hand, is still in infancy. You’ll find a good example on any given day in the newsgroups. Someone will post a solution which opens and disposes a database connection in an efficient manner, but somewhere in between concatenates a textbox value into a SQL string. This education takes some time.

In five more years I think we will be better off, but not completely there. We moved from being obsessed with scalability to expecting it out of the box in five years. However, after five more years we will still be obsessed with writing secure software, because security will still be difficult. As they say on Wall Street, past performance is not indicative of future returns.

posted by scott with 0 Comments

The Passion and the Fury of URL Rewriting

Any problem in computer science can be solved with another layer of indirection. – Butler Lampson

Since the dawn of the HttpModule class in .NET 1.0, we’ve seen an explosion of URL rewriting in ASP.NET applications. Before HttpModule, URL rewriting required an ISAPI filter written in C++, but HttpModule brought the technique to the masses.

URL rewriting allows an application to target a different internal resource then the one specified in the incoming URI. While the browser may say /vroot/foo/bar.aspx in the address bar, your application may process the request with the /vroot/bat.aspx page. The foo directory and the bar.aspx page may not even exist. Most of the directories and pages you see in the address bar when viewing a .Text blog do not physically exist.

From an implementation perspective, URL rewriting seems simple:

  1. Intercept the request early in the processing cycle (by hooking the BeginRequest event, for example).
  2. Use Context.RewritePath to point the runtime to a different resource.

If you want a comprehensive article about implementing URL rewriting and why, see Scott Mitchell’s article: “URL Rewriting in ASP.NET”, although I believe there is a simpler solution to the post-back problem (see the end of this post). I’m still looking for an ASP.NET topic on which Scott Mitchell has not written an article. If anyone finds one, let me know. Scott’s a great writer.

Conceptually, URL rewriting is a layer of indirection at a critical stage in the processing pipeline. It allows us to separate the view of our web application from it’s physical implementation. We can make one ASP.NET web site appear as 10 distinct sites. We can make one ASPX web form appear as 10,000 forms. We can make perception appear completely different from reality.

URL rewriting is a virtualization technique.

URL rewriting does have some drawbacks. Some applications take a little longer to figure out when they use URL rewriting. When the browser says an error occurred on /vroot/foo/bar.aspx, and there is no file with that name in solution explorer, it’s a bit disconcerting. Like most programs driven by meta-data, more time might be spent in an configuration file or database table learning about what the application is doing instead of in the code. This is not always intuitive, and for maintenance programmers can lead to the behavior seen in Figure 1.

Figure 1: Maintenance programmer who has been debugging and chained to a desk for months, finally snaps. It's the last time that machine will do any URL rewriting.

Actually, I’m not sure what the behavior in figure 1 is. It might be a Rob Zombie tribute band in Kiss makeup, or some neo-Luddite ritual, but either way it is too scary to look at and analyze.

One important detail about URL rewriting that is often left out. In the destination page, during the Page_Load event, it’s important to use RewritePath again to point to the original URL if your form will POST back to the server. This will not redirect the request again, but it will let ASP.NET properly set the action tag of the page’s form tag to the original URL, which is where you want to post back to.

Context.RewritePath(Path.GetFileName(Request.RawUrl));

Without this line, the illusion shatters, and people rant. I learned this trick from the Community Starter Kit, which is a great example of the virtualization you can achieve with URL rewriting.

posted by scott with 18 Comments

SCSI Is Not Magic

John Woods stopped in yesterday to clarify some of the finer points of the nasal demon effect. John has another contribution to the world of knowledge:

"SCSI is *NOT* magic. There are *fundamental technical reasons* why you have to sacrifice a young goat to your SCSI chain every now and then."

posted by scott with 0 Comments

Keeping It WS-Simple

Years ago, I helped put two large systems together. We were C++, they were Java. We were Microsoft based, they were Unix based. We were an Internet startup approaching the bursting bubble, they were a Fortune 50 company in the midst of a refinancing boom. During the initial integration we used beta 1 of the Microsoft SOAP Toolkit 2.0 (released in December of 2000). They used the Apache SOAP 2.1 toolkit (pre-AXIS), which I believe the Apache team released in February of 2001.

The toolkits worked. We moved a tremendous amount of information about mortgages back and forth. Of course, there were some hitches here and there, but nothing we couldn’t figure out after a quick search of soap-user. It was simple – just so plain and simple.

Because of this experience, I have great deal of reservations over all of these WS specifications. I believe if I were to approach that same project today, the experience would involve considerably more pain. Someone would want to use a WS toolkit here and there, and we’d be buried just trying to pass an XML fragment back and forth. It is going to take at least 3 to 5 years to shake out everybody’s interpretation and implementation of the specs to reach a plateau of interoperability, as well as revisions and fine-tuning to the specs themselves. You might say I am a member of the loyal opposition.

Do we need more standards? Yes. Do we need them now? Yes. Amazon could use them. Ted says the WS stacks are overkill for Amazon, but even though they may do millions of web service transactions, these are transactions in the loose sense of the word, not transactions in the cash flow sense of the word, just ask Carl. Everyone seems to agree the specifications are bulky and opaque. What company would offer web services for the masses based on specifications the tool vendors can’t keep up with?

After four years of web service hype, simple is still the only approach that works for everyone. It's going to be a long, slow road. It will give everyone time to mix in practical experience with the thoery of specifications.

posted by scott with 1 Comments

Shocking WS-Truth

A source entrusted me with the following paper she found at a Starbucks this summer. The hand written notes are proof of a hidden agenda lurking in the world of SOA.

I’m trying to get this to Dan Rather, but he is not returning my phone calls.

posted by scott with 2 Comments

.NET Is Coming To A Hospital Near You

As you read this there is a team of 850 people in India writing software in .NET for the healthcare industry. The company, iSoft, already has a 60% market share in the UK, and a 70% market share in Australia. They plan to target the US market in 2006.

Building enterprise scale health care software is a massive effort. Not only do they need  the general business functionality of inventory, accounting, and payroll, but there are  specialized needs in every corner of the hospital: nursing, radiology, pathology, microbiology, blood bank, admissions, pharmacy, and patient care records, just to name a few. Every one of these areas has specific needs to addresses with software.

I’ll take a wild guess and say that by 2006 this team will have 500 developer-years of work in the project. I know some other established companies in the US market. I’ll make another guess and say they have 5,000 developer-years of work invested in their solutions - but there is a huge difference.

The companies I know work in C++, and they work from scratch. They write their own hardware abstraction layers, their own device drivers, and their own proprietary database formats. It’s easy to burn 5,000 developer-years building software this way, and here is the end result: They give thier customers a custom report building application that requires instructions like the following:

VAL=IF{@account^/R.SEG.TAP %Z.rw.segment("ACT.TAP.cust.first.statement.date.
VAL=",@.db)},/R.SEG.VAL["FIRST"]

That's not from legacy software, that's from the most recent shipping version. It sure keeps the consultants and trainers busy.

On the other hand, if someone builds the software using .NET, an off the shelf relational database engine, third party reporting tools, and lets the a commercial operating system take care of, well, operating the system, they can catch up pretty quickly. At least in theory. It will be interesting to see how far they go by 2010.

posted by scott with 2 Comments

57 Steps To Avoid Kernel Panic

I tried to update my Linux distribution this week by starting over on a fresh virtual PC. I tried SuSE 9.1 Personal only to have a kernel panic early in the installation. Then I tried Fedora Core 2 only to have another kernel panic. That’s when I began to suspect a more sinister problem and found this bug entry - complete with a 57 step work around.

Maybe I'll just wait three months and try again.

posted by scott with 4 Comments

Static Constructors & FxCop

I’ve found static constructors very appealing in .NET class design. I think this is partially due to coming into .NET with a C++ background. Although there are techniques available to achieve the same effect in C++, the language did not have the syntax to support the concept as elegantly.

The first time I received the “Do not declare explicit static constructors” message from FxCop I was a bit dismayed. Why is it telling me there is a performance penalty for a static constructor? One caveat I’ve always had with FxCop is that the tool enforces design guidelines for a framework, and these guidelines are not necessarily the same guidelines you’d want for an application. To get to the bottom of the critical warning message about static constructors required some research.

The key is a metadata flag the compiler adds to a class without an explicit static constructor – the beforefieldinit flag. In the code below, both Foo and Bar should appear identical in their behavior, and really they are almost identical if you look at both with a decompiler. The difference is, Foo will have the beforefieldinit flag, and Bar will not.

class Foo
{
    public static string Message
   {
      get { return _message; }
   }
 
   static string _message = "Hello World!";
 
}
 
class Bar
{
   static Bar()
   {
      _message = "Hello World!";
   }
 
   public static string Message
   {
      get { return _message; }
   }
 
   static string _message;
}’

Brad Abrams has some details about beforefieldinit in his blog post from earlier this year. However, after doing some experiments I’d give a slightly different description about the effects of beforefieldinit.

The beforefieldinit flag allows the runtime to be very ‘eager’ in calling a static constructor, a.k.a a type initializer. This is in contrast to being lazy and calling the static constructor at the last possible moment (in hopes you might not need to call it at all). The difference between eagerness and laziness can be demonstrated by timing the following code using Foo and then Bar.

for(int i = 0; i  <  Int32.MaxValue - 1; i++)
{
   string s = Foo.Message;
}

In my experiments, looping with Bar (explicit static constructor) will perform about 5x slower than looping with Foo (implicit static constructor and beforefieldinit set). With Bar in the loop, the runtime must invoke the static constructor at the last possible moment (the spec says it), so the check to see if the type constructor needs invoked is inside the loop. With Foo and the beforefieldinit flag, the runtime is free to eagerly execute the static constructor before the loop starts and thus avoid the overhead of further checks.

Obviously I’ve created a worst case scenario to see the possible performance impact, and performance should not always dictate design decisions. Still, I’m a little disappointed that my beloved static constructors feel a little bit tainted now.

posted by scott with 0 Comments

Community Starter Kit Resources

If you are looking for online resources about the ASP.NET Community Starter Kit, here are a couple places to look:

Stephen Redd’s Site (full of CSK Articles, Mods, and Fixes)

Dave Rank’s Personal Web Site

Matthew Roche’s CSK Resources 

posted by scott with 0 Comments

The Football Pool

Football season (American) started today. To be precise, it started on Thursday night, but since we never had football games on Thusday nights when I was growing up as a kid, I tend to pretend this doesn’t happen.

A few years ago, my interest in pro football was on the decline. This was around the time when football began to morph from being a team sport into a form of modern dance, and players began to augment their costumes with cellular phones and permanent markers. Plus, the Steelers can never seem to get back to the super bowl, so, really, who cares?

One way to make anything interesting is to have a pool. A pool is where a bunch of people will put money into a pot and predict the outcome of some event, like football games. Whoever picks the highest number of game winners correctly wins a percentage of the pot.

Being in an office football pool is not about winning money, which might be enough to buy lunch for two. It’s about winning the pool and having bragging rights for a week. Winning means going to work and pretending you really knew what was going on when you made your winning selections, even though you might not have done it alone.

Me: “Alex, who do you think will win – the Eagles or the Browns?”

Alex (my now five year old son): “What is a Brown?”

Me: “Well .... it’s basically a dull color”.

Alex: “Eagles!”.

A few years ago I started a little pool at the office by sending an email to the staff@ alias (first mistake). This brought a response from the human resources department that football pools fall into a ‘legal grey area’ and I should refrain from mentioning ‘football pool’ at work. No problem, I thought, I had an email list of 30 people interested in a little fun, so I fired off an email to this list without actually checking who was on it (second mistake). Well, it turns out our CFO was on the list, and I’m not sure why, because he never actually played in the pool, but he did, it seems, mention to HR that I was running a football pool.

The next day I stood in the office of the Supreme Ministry Of Human Resources and explained why I disobeyed a direct order. I had to cross my heart, and swear that I would not be using company resources to run illicit gambling activities. It was the last pool I ever ran, and my time spent watching football is asymptotically approaching zero. If the Steelers make the playoffs, somebody please let me know.

posted by scott with 2 Comments

I, Speak

On October 5, 2004 I’ll be talking about the Community Starter Kit for the CMAP .NET User Group meeting in Columbia, MD. I plan to focus in on a couple key pieces of the architecture that can be applicable to ASP.NET applications today and tomorrow. The presentation will stay practical, and I hope to use only two buzzwords during the talk: indirection and virtualization.

To finish the talk I’ll touch on customization and deployment of the CSK, which hopefully doesn’t put everyone to sleep. If it does, I plan to make off with all the free pizza, soda, and raffle prizes before the audience wakes up.

On October 16th and 17th I’ll be at Microsoft’s Waltham, MA facility for Code Camp II: The Return. I have a session to talk about techniques for integrating SQL Server Reporting Services into ASP.NET applications. Although I have not spent much time with the report designer I have spent a fair amount of time investigating ways to hook into SSRS programmatically. This talk will focus on improving the sample report viewer component for use in the real world, and tips / tricks / traps with the web service API.

I only hope my session doesn’t overlap with some of the sessions I really want to see while I’m there, because there is some great looking content and speakers. I also hope this software developer from Boston doesn't show up, because quite frankly, she scares me.

I have a slew of SSRS articles to build from, you’ll probably see more here soon as I work on the presentation.

Authentication, Role-based Security, and SQL Reporting Services Web Services

Introduction To Role-Based Security In SQL Server Reporting Services

The Blog Delivery Extension

 Embedded Code In Reporting Services 

Using GetReportParameters in Reporting Services 

Using CreateSubscription and the Reporting Service API

SQL Reporting Services Tree Navigation Sample using a Web Service API

posted by scott with 0 Comments

You Heard It Here Second

This just in from the Microsoft Downloads RSS feed!!

Microsoft Calculator Plus is now available!

Update: The CalcPlus link seems to lead nowhere now. It really did exist for a time. Donna Buenaventura saw it too. The plot thickens....

Everyone has been talking for years about how Microsoft has killed calculator innovation by including calc.exe with the operating system. After all those messy anti-trust suits and allegations of anti-competitiveness, Microsoft has finally answered the critics. The calculator dev team has been back in feature development mode. A new age of calculation is upon us. Prepare your eyes as I now convert barleycorns1 into feet!!



1: From Sizes.com. In England and Scotland, at least as early as the 12th century an inch was thought of as 3 barleycorns laid end to end. A document of 1474 states: “III barley corns take out of the middes [middle] of the Ere make an Inche and XII inches makith a foote and III fote makith a yarde.” 

posted by scott with 3 Comments

SQL Gets Schema

When I first started working with SQL Server (v 7.0), I found two part / four part names a bit confusing:

            SELECT * FROM ownername.tablename
            SELECT * FROM servername.databasename.ownername.tablename

What would confuse me was why anybody would want an owner name - a login - appearing as part of a fully qualified database object name. This creates all sorts of limitations. If an admin needed to remove a user, all the objects belonging to the user had to be dropped or reassigned – breaking all queries, views, and stored procedures with two part names. Since nobody wanted to tie an object to a user, we created databases where dbo owned all objects – forcing permissions to be granted on an object-by-object basis.

Linking users to objects also created all sorts of unfortunate naming conventions. Take .Text for instance, which prefixes all database object names with “blog_”. Likwise, the Community Starter Kit prefixes all object names with “Community_”. This practice allows these applications to work in hosted environments and share a common database without object naming collisions, but it feels ugly.

Thankfully, SQL Server 2005 gives us schema. Objects now belong to a schema. A database may have multiple schemas.

            SELECT * FROM schemaname.tablename
            SELECT * FROM servername.databasename.schemaname.tablename

No longer does the designer have to worry about naming conventions to group tables. A database designer can instead think about what the functional area of a table will be. For instance, the new AdventureWorks sample database in 2005 groups user tables into schemas like “HumanResources” and “Shipping”.

Schema separates users from database objects and functions similar to a namespace. The schema is also a container, and permissions can be assigned at the schema level instead of on individual objects. Schemas are an additional layer of indirection. Admins can drop users without worrying about reassigning object ownership. Schemas are flexible. Queries with two part names don’t feel so brittle anymore.

I thought of a little saying. It goes like this:

Users come and go, but schemas are forever.

Is this poetic? Or Corny? Does it belong in a book of prose? Or printed on some t-shirt and sold at a discount stand by the beach?

posted by scott with 2 Comments

Chocolate Technology

John is addicted to chocolate. I think I am too. Just recently, I noticed a new product in the vending machine at work. It’s a chocolate bar with miniature M&M’s inside. Just think – you have pieces of chocolate inside of hard candy shells then embedded into a larger bar of chocolate. Human achievements just never cease to amaze me.

I somehow resisted the urge to plunk money into the machine and go on a chocolate feeding frenzy. I wish they wouldn’t keep these in the machine - it would be much easier to resist the spicy pork rinds Heather finds in the vending machines at Microsoft. I’m 40 pounds lighter than I was in 2002 and I’m not going back. I carefully monitor my chocolate intake.

In my searches for the latest in chocolate tech, I discovered the “Course In Chocolate Technology”. This course covers everything from cleaning, roasting, winnowing, and grinding the cocoa bean to chocolate viscosity exercises with polyglycerolpolyricinoleate. Doesn’t that sound yummy? Maybe understanding the underlying science and chemicals of modern chocolate manufacturing would cure my addiction.

posted by scott with 0 Comments

The Pharmacist and .NET Performance

I listened to the .NET Rocks episode with Jeff Richter this week. At one point, Jeff made a comment about C# having an inherent performance benefit over VB.NET. About two beats after Jeff finishes the statement you hear Carl suck in air. I think he wanted to explode at this point but winced instead.

Carl is a fervent supporter of VB.NET and dispels all sorts of myths about the language. Carl told Jeff he didn’t agree, but didn't start a debate. Jeff commands a great deal of respect in the .NET community, as well he should, but I think the truth is somewhere in the middle.

I don’t think the C# code from a competent, professional programmer would show a noticeable difference when compared to the performance of the same implementation written by a competent pro in VB.NET. When it comes to the hobbyist who doesn’t know what “option strict” does, (and doesn’t care) however, this is where you see the spread.

About one year ago I met a pharmacist who wrote an application in ASP.NET. The application tracked drug-drug interactions for patient safety. It was a great implementation of the pharmacist’s domain knowledge. The application worked. Would I have shrink-wrapped the code and put up for sale? No. Was it scalable? No – but, the point is, this fellow was putting his expertise to work, and his expertise wasn’t in building a scalable web site.

If someone put this application through a stress test, they might conclude that the entire .NET platform isn’t scalable. Just like political sound bites – you sometimes have to put a piece back into context before making a judgment. Perhaps this perceived performance difference isn’t really because of the different compilers, but because there is a significant percentage of VB.NET developers who don’t change the default setting of option strict (off by default). Late binding is a drag.

I do think there will be a divergence in the future between C# and VB.NET if VB.NET continues to layer higher levels of abstraction on top of the base class library (like the My keyword in 2005). As long as you know the underlying framework, it still shouldn’t matter much in the time trails.

posted by scott with 1 Comments