Saturday, September 16, 2006

.NET 2.0, HttpWebRequest.KeepAlive And ServicePoint.ConnectionLimit

Since switching over to .NET 2.0, one of our applications occasionally threw "The request was aborted: The request was canceled." resp. "The underlying connection was closed: The request was canceled." errors. This happened maybe 1 out of 25 times when connecting to another server using HTTP, either directly via HttpWebRequest or on webservice calls, which also apply HttpWebRequest internally.

Digging further into the issue, it turned out that several people suggested to set HttpWebRequest.KeepAlive to false. And as matter of fact this worked. But KeepAlive=false will most likely imply a performance penalty as there won't be any re-use (also known as HTTP pipelining) of TCP-connections. TCP-connections are now closed immediately and reopened on each HTTP-request. To make things worse, we have SSL turned on, with both server and client certificates, so KeepAlive=false will then cause a complete SSL-Handshake now for each and every HTTP request to the same server. As a sidenote, KeepAlive=true with client authentication requires the initial authentication to be shared between all following requests, hence it is necessary to set HttpWebRequest.UnsafeAuthenticatedConnectionSharing=true. Please consult the MSDN documentation for more information about what that implies.

Back to the original topic, our application used to work fine under .NET 1.1, only .NET 2.0 seems to have this problem. And despite the fact that people have posted this issue over and over again, there is no Microsoft hotfix up to this day. KeepAlive=false is the only remedy.

By the way, another property that is essential for network throughput under .NET is HttpWebRequest.ServicePoint.ConnectionLimit. Microsoft started limiting the maximum number of parallel network connections some time ago (I once read in order to prevent malware from flooding the network - which sounds unlikely given that one can simply raise this limit programmatically, at least with admin credentials), and while this might not harm the single user when surfing the web, it surely is not suited for other kinds of applications. After the limit is reached, further request will be queued and have to wait for a running request to terminate. I am sure there are quite some applications out there which run into performance problems because of this.

The preset connection limit might vary depending on the underlying operating system and hosting environment. It can be changed programmatically by setting HttpWebRequest.ServicePoint.ConnectionLimit to a higher value, or in one of .NET's .config files (machine.config, app.config resp. web.config):

<system.net>
<connectionManagement>
<add address="yourtargetdomain.com" maxconnection="32">
</add>
</connectionManagement>
</system.net>

This is just one of many possible explanations, but that unfortunate limitation might boil down to a particular interpretation of RFC 2616 (HTTP1.1), which states:

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion.


So is any .NET application considered "single-user client" by default? Our system surely isn't a single-user client, it's more like a kind of proxy, with plenty of concurrent users and HTTP connections. And how many developers might now even have heard about this setting, and will find out once their application went into production?

Also note that phrase of "persistent connections". Of course it is a bad idea for the client to hold hundreds of connections captive and thus bringing the server to its knee. But as I have mentioned, we cannot pool any connections anyway, not even a few of them, thank's to .NET 2.0's "The request was aborted: The request was canceled."-bug.

Anyway, it's the server's responsiblitlity to determine when too many connections are kept alive. After all, HTTP-KeepAlive is something that the client might ask for, but that the server may always decline.

Wednesday, September 13, 2006

Jeff Atwood Takes On Joel Spolsky

Jeff Atwood openly asks if Joel Spolsky "jumped the shark" because of implementing their his company's flagship product FogBugz in an in-house Basic-dialect called "Wasabi". Wasabi can then be compiled to VBScript or PHP, depending on customers' requirements.

Back when I read about this approach, it made me raise an eyebrow as well. I remember thinking, "boy I thought I'd like to work at Fog Creek, but having to code in such a proprietary language would be no-go". And I was wondering if that wouldn't contradict their frequently mentioned efforts of trying to attract great programmers. Actually, of the best programmers I know, nobody would ever voluntarily program in something like VB or VBScript, let go Wasabi.

But he then went on describing how this decision made sense from a business point (platform independence at a minimum of effort, no complete rewrite necessary), so I said OK, I might not like it from a developer's perspective, but from a business perspective it could make sense.

Now Jeff Atwood probably is a more censorious person than me. He decided to rip apart Joel's argumentation and connect the Wasabi-story with Joel's criticism of Ruby. He continued to make some pretty hefty statements like "fifty thousand programmers' heads simultaneously exploding", "absolutely beyond the pale" or "amplifies the insanity". I usually like Jeff's artwork, but attaching a big red WTF label on Joel's forehead is not really subtle either. And the flaming continued in the comment sections of both blogs.

My recommendation: Please settle down! From reading one or two paragraphs in some Joel on Software article, nobody possesses the same amount of information that Joel Spolsky was basing his decision on. Also, recognizing that what seems right from a developer's view must not always be right from a business standpoint is something that many programmers still have to get into their minds.

But hey, let's not hang on each of Joel Spolsky's words either. He certainly is an extraordinary programmer and writer, but he might be mistaken as well at times (a possibility he openly admits).

Thursday, August 31, 2006

Vanilla DAL: Added Support For OleDB And Oracle

3:00am in the morning, I finally managed to add support for Oracle and for the generic OleDb ADO.NET provider (using MS Access, as this was all I had available) to Vanilla DAL. Client code stays free of database specifics, but I am still wondering what to do with SQL statements. Vanilla DAL enforces SQL statement externalization in XML resp. generates SQL on-the-fly, but I can't (and won't) prevent the developer from applying vendor-dependent SQL syntax. The format of parameter placeholders is vendor-specific as well... I am probably going to set up one global standard, and wrap away vendor details for SQL parameters.

I am planning to publish Vanilla DAL 0.2.0 within the coming week. Next task will be to provide documentation and more samples. After that is done, it might have reached a state which allows me to start promoting this framework (it's more of a skunkworks project right now).

Wednesday, August 30, 2006

Vanilla DAL 0.1.2 Released

I just released version 0.1.2 of my .NET data access framework "Vanilla DAL". Currently I am working on support for Oracle and OleDB providers, and this release lays the groundwork for the oncoming changes on an API level. When this is done, Vanilla DAL will move from pre-alpha to alpha status.

Installing Oracle 10g express edition was a time-consuming task, as always with Oracle. Being a small footprint edition, it seems to be consuming too many system resources for my taste. On the other hand, the administration tools have improved tremendously (remember those Java rich clients on Oracle 8?). Anyway, my best Oracle days are long gone (Oracle 5 in 1992 on DOS, Oracle 7.3 and Oracle 8 between 1997 and 2001 on DEC VAX, Sun Solaris and finally Windows). This time I only plan to migrate my test database over there, get the Oracle-specific implementation done and that will be it.

I am not quite sure if I will manage to keep the complete API backward compatible to the previous releases, this mainly has to do with the fact that ADO.NET data providers enforce different SQL parameter naming conventions (e.g. @name under SqlServer, ? under OleDB, :name under Oracle). The most important issue is to prevent any DB-specific code in application modules. As there is no parameter name but only a parameter position under OleDB, I am still looking for the optimal mechanism to hide this detail from application code.

Wednesday, August 23, 2006

Visual Studio .NET 2003 SP1

It's finally here.

Three and a half years after Visual Studio .NET 2003 had been published and nearly one year after it's successor Visual Studio .NET 2005 saw the dawn of light, the first service pack for 2003 became available last week. And it is going to save us tons of otherwise wasted time (we are still stuck with .NET 1.1 in this project because of some third-party libraries that just won't work under .NET 2.0).

Over the last years, we have experienced all kind of difficulties with Visual Studio 2003. One of my "favorites": Controls disappearing unpredictably in WinForms designer. After a while we even figured out what was going on under the hoods, how the designer generated initialization code in a different order when child controls were being added to parent controls, in case the parent controls had in turn had been created AFTER the child controls. This consecutively led the designer to throw away parts of the code during the next code generation cycle. We already knew how to rearrange the originally generated code segments, so we managed to prevent that from happening (if that does sound sick to you, you are not alone).

But one of the biggest productivity killers was the incredible amount of time it took WinForms designer to open complex forms, e.g. forms with lots of controls spread over several tabpages. It lasted minutes of up to 100% CPU usage on typical developer machines in 2003 (remember, no dualcores back then) and required close to a Gigabyte of additionally allocated memory. Sometimes the IDE crashed during the process and we had to start all over. I blamed the third-party controls we used. They probably misbehaved at design time. Never would Microsoft have left such a bug unpatched for more than three years, right?

Wrong!

The following CPU and memory usage charts represent the same activity - opening our most complex form in Visual Studio 2003 WinForms designer on a dualcore Pentium 4 3.0GHz with 2 Gigs of RAM.

Visual Studio 2003 w/o SP1: 90 seconds, memory allocation 800MB:

(Core 1)
(Core 2)
(Memory)

Visual Studio 2003 SP1: 10 seconds, memory allocation 20MB:

(Core 1)
(Core 2)
(Memory)

Tuesday, August 22, 2006

Test Automation For .NET Winforms Applications

I had been searching for a decent test automation tool for one of our .NET client/server applications for quite a while now.

Of course there is NUnit for unit testing, but our application is very userinterface-heavy, and while we will continue to provide NUnit test cases, they only cover one part.

Then there are the big players in user interface test automation like Rational Robot or Mercury QuickTest. But the licensing costs seemed disproportional here.

We actually have applied some of those tools on other, larger projects, e.g. I used to work on an Enterprise Java solution where one of my colleagues was solely responsible for maintaining and running a suite of test cases (Rational Robot mainly). For Java web as well as Swing rich client applications there is Apache JMeter, but I don't know of any .NET port. HttpUnit allows for testing at HTTP level by emulating browser behaviour. In .NET land we now have Microsoft Software Tester Team Center for Visual Studio 2005 / .NET 2.0. I am very impressed with what I have seen about Team System in general, but in this project we are stuck with .NET 1.1 at the moment.

One product I was particularly interested in just was a real pain in getting it up and running - downloading and registering additional plugins, just do find out it wouldn't work, that kind of stuff. So I gave up on that one. Of course, this vendor will have a sales representative call in some days after you filled in the download form. All I wanted was to download the trial version (if they ask for my email that's OK, but having to enter my phone number usually is a warning sight), and have it up and running within five minutes so I can start playing around. If that's not possible, it's a no-go.

Besides I only digged out some half-baked freeware solutions for .NET. Of course, as .NET WinForms are based on native window handles, any Win32 user interface test tool might have been fine as well. User-drawn controls are a little problem, as the test tools cannot attach to any handles of child controls, so they will only record screen coordinates on mouse-events. E.g. if your pulldown menu is user-drawn (the whole menu is represented by one single Window handle, but there isn't a Window handle for each menu item), and you add another menu item on top of others, your mouse-click coordinates won't fit any more.

Anyway, one of my colleagues finally stumbled upon AutomatedQA TestComplete. It was easy to use from the first moment on, came with all the features we need, had strong scripting capabilities, and was labeled at a fair price (USD 499 for the standard edition). Right now we are in the process of assembling a little test script library, and we are recording our first test cases. After a test case has been run, the script continues to check the database for valid processing. We are planing to run those scripts automatically each night on the latest source version.


I will continue to report about our experiences with TestComplete.

Saturday, July 29, 2006

The Upside-Down-Ternet

So if your wannabe-hacker neighbour intents to steal bandwitdh from your WLAN, instead of using WPA you could rather turn the (ip)tables and set up his own Upside-Down-Ternet.

Monday, June 26, 2006

Software Engineering Radio On Model Driven Software Development

Great series of podcasts on model driven software development by the folks from Software Engineering Radio. I spend some time last weekend listening to...


... and also pointed my coworkers to those episodes in order go get all of us jump-started on MDSD, a topic which will be becoming of major importance in one of our upcoming projects.

Friday, June 16, 2006

Ruby On Rails

If you are developing web applications under J2EE just like me, and also grew increasingly curious about all that hype around Ruby on Rails lately, you might want to have a look at the screencasts available at rubyonrails.org. Having watched some of the presentations, it's certainly too early to draw any conclusions yet. All I can say is that Ruby on Rails looks like an extremely productive environment. Hacking prototypes that way seems like a very natural thing to do. On the other hand, there is a lot of magic going on. And I don't like magic, at least not too much of it. I am also one of those old-fashioned developers who prefer to pass their code through a compiler before running it. Still, I will definitely take a closer look on Ruby on Rails as soon as my schedule allows me to.

Thursday, June 15, 2006

Gates To Leave Day-To-Day Role At Microsoft

News of the day: Microsoft announced Thursday that chairman and co-founder Bill Gates will transition out of a day-to-day role at the company, effective July 2008, to spend more time working on his charitable foundation.

Having read a lot on Bill Gates' biography over the years, I am a little bit surprised by this step. He had been showing such a lot of drive and dedication for the software business for more than thirty years. The people who challenged him, Gary Kildall (DR), Mitch Kapor (Lotus), Ray Noorda (Novell), Jim Cannavino (IBM), Philippe Kahn (Borland), all of them kissed the dust sooner or later. I am not sure about Eric Schmidt and Google yet ;-) Anyway, and whether people like it or not, Gates is leaving the ring as undisputed champion.

Sunday, June 11, 2006

Dolphin Filemanager For KDE

My friend Peter has now published a first alpha version of his Linux filemanager codenamed "Dolphin". It is being implemented in C++, based on Qt. I know Peter's works from several years of joined efforts on a C++ framework, so I can really recommend Dolphin to Linux desktop users in KDE camp. Unlike Konqueror, Dolphin supports file operations exclusively and emphasizes on usability and performance.

Please give it a try, and tell Peter what you think about it.

Saturday, June 10, 2006

Totally GridBag

Ironically I found this video scoffing at the infamous Java GridBagLayout the very same day I helped a friend on some GridBagLayout code. I thought I had finally achieved GridBagLayout mastery after years of practicing ;-). One of the first things in any AWT or Swing project used to be a subclass of GridBagConstraints with some convenience constructors for setting the property values all at once. But in the days of UI designers like Matisse I seem to have forgotten again some GridBagLayout specialities. Well, maybe that's not even a bad thing.

Wednesday, May 24, 2006

Marc Andreessen Speaks At Berkeley

Sorry for not posting in a while, I am once again in release crunch mode.

I listened to Marc Andreessen speaking at the UC Berkeley Distinguished Innovator Lecture series the other day (webcast link, podcast feed), talking about career decision making, the fallacy of working in large corporations and how tech startup venture capital funding changed within the last ten years. He also mentions that after graduating - while expecting to be a programmer for the rest of his life - he only worked as a software engineer for about three months (supposedly referring to his short interlude at Enterprise Integration Technologies before founding Netscape together with Jim Clark). Supports my impression that he didn't really do any coding on Netscape Navigator.