Monday, February 26, 2007

What Set You Claim? (Server Software)

{

Royal Pingdom did an analysis of what "popular" sites are running beneath the hood (as easy as a query at Netcraft). Royal Pingdom reveal themselves as a certain "persona" (yeah, I'll overgeneralize for now) by their choice of sites: Technorati, Meebo, Feedburner and so on.

It probably isn't surprising that most of these sites run on Linux with Apache and MySQL involved somewhere on the back end. I'm surprised (of course I'm not in the LAMP game though) to see a bit of a surge in the use of Lighttpd - a more lightweight serving engine than Apache.

As a developer confined to the realm of Microsoft tools it's a bit disappointing albeit unsurprising. What lies beneath the statistics at Royal Pingdom is something bigger and more crushing: the people that seem to be at the forefront of thinking and building the web don't use our tools. Our tools are the favorite of the commoditized environment of your average big company - less thinking and less innovation.

In part I can see a chicken and egg scenario: people building startups and experimenting need a cheap platform upon which to do so. One doesn't license Windows Server, Visual Studio, SQL Server, and so on with a poor [wo]man's budget when comparable free tools exist. In other words, I would assume that some market economics are behind the choice of platform.

But if you're a person like me in the Microsoft space, perhaps a big part of the frustration of working within an environment that lacks passion and quirky inventiveness is that the birds of a feather live in a different place and use a different technology. Of course I work with a lot of people who are excited and innovative - and beyond my coworkers there are quite a few people pushing the envelope with Microsoft tools. But I'd say in general that a corporate developer has a different set of values and goals than the kind of person who would build at a startup. As time passes I see this less on a "success" angle - most types seem to do well enough for themselves - and more of a clustering of similar people.

The bright spark on Royal Pingdom's list is Alexaholic built buy Ron Hornbaker which follows a pattern I'd like to follow as an ideal - that a person can use Microsoft technology (with which I'm quite familiar) and implement any good idea. Beyond that, there is an advantage to a smaller pool of innovators - there is more room for folks like me who may not have the best ideas in the world, but who are good enough to perhaps take something from the startup/open source space and port it.

}

Monsterbugs: Any silver bullets?

{

A few weeks ago our client began to report errors with our Windows Forms (.NET 2.0) application when she'd retrieve certain records. It was a strange bug that would hang the program for about 60 seconds and then crash without reporting errors. We could reproduce it on the test machine, but in development even while pointing to the same database, everything worked. Perfectly.

I looked in the Event Log and noticed the following error:
"Faulting application epicenter.exe, version 1.0.0.0, stamp 45df84bf faulting module kernel32.dll, version 5.2.3790.2756, stamp 44c60f39, debug? 0, fault address 0x00015e02"
Really, really helpful stuff. And especially because this wasn't something we could get in development, on any of our boxes, it was confusing. Google searches weren't giving specific answers - the error seemed to general in the realm of .NET 2.0 to make much of -

So how do you pin something like this down?

My approach was as follows:

// code to load data
MessageBox.Show("Loaded data");
// code to display data
MessageBox.Show("Displayed data");

Our application is not small. The form that displays data contains 3300 lines of non-wizard generated code. Data is loaded from a set of methods in a separate library which itself may have upwards of 3000 lines, not to mention that that library references yet more libraries*... my point here is that it's not a small script to throw a dialog up after each line or call.

In the end I spent about 4 hours stepping through each of the major calls via dialog messages. I couldn't debug since our test machine doesn't have Visual Studio or other debugging tools on it (like all the other machines in their offices).

Although I think we've done a good job breaking the logic into pieces (ie. one method for getting data, one for display that is broken into methods for customizations on each object) it was still difficult to discover.

And in the end, of course, it was something small and subtle: calling the AutoColumnsResize method of a DataGridView can sometimes throw exceptions - because of the recursion of the resizing combined with the paint operation of the Windows Forms application. What was probably most annoying was that it wasn't even my code that was responsible for the hanging exception, it was the framework's inability to recover from an internal exception.

When I first started troubleshooting I thought I should have elaborated more on a "tracing" level in our application - we trace some exceptions but not all to the database. But when I finally found the bug, especially because it wasn't in the code we were responsible for writing, I doubt it would have done more than just save time. A stack trace would probably have helped as well, if caught at the point of the exception. But my big question is whether there are any well trodden techniques for finding and dealing with bugs like this, especially if they are in the framework and not in one's own code. How do you deal with stuff like this, or is it always a slog for which there is not silver bullet?

*I think the design of the application is okay (duh, I'm the one responsible) but it may sound more convoluted in that statement than it actually is. We've got a DataHelper library that is covered by unit tests which does all of our data access at the database level. It runs stored procedures, deals with parameters, and so on. One level of abstraction higher we've got a set of business layer objects for dealing with the entities related to our application: loans, disbursements, checks and so on. The Windows Forms application is what we use to let the user display/enter/modify data. We've got a few additional libraries for tracing, configuration, format, data validation, and Crystal Reports. Not so bad I hope...

}

Friday, February 23, 2007

Configuration Ammendment

{

// get calling assembly settings classstring
assemblyName = System.Reflection.Assembly.GetCallingAssembly().FullName;

I had used the above in my previous code sample to retrieve the assembly name before obtaining settings from the config file. It works only if you are attempting to obtain configuration information from a library that is called by an *.exe. But what if you are in a library (*.dll) and you are using another library to read configuration information as I'd planned? The Assembly.GetCallingAssembly().FullName returns the name of the library, which as I mentioned before is not where the Configuration class naturally looks for settings. Using the following modification:

// get calling assembly settings classstring
assemblyName = System.Reflection.Assembly.GetEntryAssembly().FullName;


Ah, much better. A subtlety worth remembering: Assembly.GetCallingAssembly() returns a reference to whatever the caller, whether it's a library or executable whereas Assembly.GetEntryAssembly() will give you the name of an executable responsible for making that first call to the framework.

Interestingly, in an ASP.NET 2.0 application where the runtime is processing libraries directly, Assembly.GetEntryAssembly() returns a null.

}

Thursday, February 22, 2007

Settings, Configuration, .NET 2.0

{

A while back I complained about configuration within Windows Forms applications, mostly because I lacked an understanding of the API. I hacked a simple xml file together wherein I could store simple name value pairs that we'd utilize for the application and surprisingly it's been the approach for quite some time.

I've been studying for the Microsoft 70-552 exam which would update my "MCAD" certification to "MCPD." I know, I know, certification is frown upon by so many people who think I should really be reading The Little Schemer to do cool parlor tricks. But this is a case where what I'd said earlier about certification rings true: it probes for weakness and exposes where you "fake it" with hacks without understanding the real structure and purpose of the technology. Case in point, configuration.

In my earlier post, I'd used Configuration.AppSettings which I now know as deprecated. Instead there's a nifty configuration/settings API one can leverage. What I've done here is based very heavily on Chris Sells's Windows Forms 2.0 Programming although I took liberty to modify some of the code to make it more reusable and generic (his intent was to show basics).

The first stop one needs to make is to add a Settings file to the project along with a reference to System.configuration (not sure why configuration is not Configuration).



Underneath the properties node if you "edit" the settings file, it's really a grid that allows you to enter settings with a key, datatype, scope, and value. The scope in here can be either as a user setting or an application setting - it's also possible to write your own section handler and extend the model.



After compiling this is converted into your app.exe.config file - the physical storage of your settings in the xml format well know to config files.



The code for retrieval is still, in my own view, a little verbose but it's easy to develop a simple accessor helper class. Even more slick in the design of the .NET Framework is that class library projects (DLLs) pull configuration settings from their hosted EXE so you the utility code here is from a DLL designed to be referenced and used from any application.

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;

namespace SettingsGroperLib
{
public enum SettingType {
userSettings,
applicationSettings
}

public class ConfHelp
{

public static string GetConfSetting(SettingType settingType, string settingKey) {
// obtain current configuration
Configuration currentConfig =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// obtain section utilizing enumeration
ConfigurationSectionGroup group =
currentConfig.GetSectionGroup(settingType.ToString());
// get calling assembly settings class
string assemblyName = System.Reflection.Assembly.GetCallingAssembly().FullName;
// yah, it's ugly, but it works
string friendlyName = assemblyName.Split(',')[0];
// obtain section by combining friendlyname to settings class
ClientSettingsSection section =
(ClientSettingsSection)group.Sections.Get(
String.Format(
"{0}.Properties.Settings",
friendlyName
)
);
// get setting key
SettingElement element =
section.Settings.Get(settingKey);
// return settings value as
return element.Value.ValueXml.FirstChild.Value;
}

}
}

Sorry about the format; you can download a nice formated version here.

It all seems so easy once you take the time. I think the unlearning was a big obstacle for me since working with config files was something I did all the time in .NET 1.x and old habits die hard. Oh yeah, the retrieval:

string test = ConfHelp.GetConfSetting(SettingType.applicationSettings, "DBUrl");

}

Monday, February 19, 2007

Top Ten Mistakes of Web Design

{

Jakob Nielsen just updated his list of top ten mistakes a web designer can make. I've got no clout like he does but my number one annoyance in web design is when people work against the browser.

The best example of this in my mind is the back button. On so many projects I've had "issues" submitted related to the use of the back button and had to write code to try to cheat the browser into not allowing its use. But the back button is there for a reason and working against the browser is almost always futile: trying to prevent using backspace, alt+arrow, right clicks, programmable mouse buttons, pasting to multiple browser sessions... at what point do we just allow users to keep their control?

I like apps that tolerate issues related to browser control - they let you do it but when they croak, it's an edge case that they aren't willing to reprogram the entire system for. I wish more people would grok the fact that browsers simply aren't fat clients and they've got to share control.

}

Language and Thinking

{

I'm fortunate enough to be sitting in on some training and the ice breaker at the beginning was to say which language one liked the most. Most in the room went with what they use for work, C#, but of course I had to break the flow and say I prefer Perl and Javascript in terms of raw language more than anything at the moment.

Talking about it later I brought up the old Sapir Whorf notion of language affecting thinking and problem solving and it's funny how you have a thought and seems to start jumping out at you all over the place. Tonight I ran into (courtesy of Raganwald) the following quotes regarding that idea:

"The connection between the language in which we think/program and theproblems
and solutions we can imagine is very close. For this reasonrestricting
language features with the intent of eliminating programmer errors is at best
dangerous." - Bjarne Stroustrup

"The very fact that it's possible to write messy programs in Perl isalso what
makes it possible to write programs that are cleaner in Perlthan they could ever
be in a language that attempts to enforcecleanliness. The potential for
greater good goes right along with thepotential for greater evil." - Larry Wall

}

Wednesday, February 14, 2007

Wow

{

Microsoft's Vista Ad - quite a contrast to the Apple commercials. To the degree that commercials evoke a sense of a company's ideals, it's telling of something I've always thought of when comparing Microsoft to others - they are trying to solve harder problems than the home movie or virtual greeting card.

Of course, they could just be playing to my ideals and trying to make money out of it...

}

Saturday, February 10, 2007

Vote Hanselminutes

{

I'm just echoing the words of Chris Sells's post to vote for Hanselminutes on Podcast Alley. It's my personal favorite among technical podcasts.

}

Wednesday, February 07, 2007

Queues with SQL Server 2005 Service Broker and C#

{

I recently had to set this up and didn't find all too many resources online. I don't have time for a full commentary but suffices to say this: SQL Server 2005 has some excellent reliable messaging capabilities through what's called Service Broker. If you, like me, are a complete skeptic when it comes to new products, this is what I think of as a compelling feature. In the following example, I'm setting up a queue for FileIDs - assume these are identifiers for files that need to be processed asynchronously. After I created my database in SQL 2005, I opened up the query tool and went ahead with the following TSQL:

-- you can attribute an hour to finding this requirement :(
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Password1';
GO


-- message, contract, queue, service creation
CREATE MESSAGE TYPE FileIDForQueue
VALIDATION = NONE;
GO

CREATE CONTRACT FileQueueContract
(FileIDForQueue SENT BY INITIATOR)
GO

CREATE QUEUE dbo.FileIDReceiverQueue
GO

CREATE QUEUE dbo.FileIDSenderQueue
GO

CREATE SERVICE SenderService
ON QUEUE dbo.FileIDSenderQueue
GO

CREATE SERVICE ReceiverService
ON QUEUE dbo.FileIDReceiverQueue (FileQueueContract)
GO


In order to leverage the queue, I wrote the following stored procedures to enqueue, dequeue, and peek:

/*
STORED PROCEDURE RESPONSIBLE FOR INSERTING A QUEUE ITEM
*/
CREATE PROC spSendFileToQueue
@FileID INT
AS
BEGIN TRANSACTION;
DECLARE @conversationID UNIQUEIDENTIFIER
BEGIN DIALOG CONVERSATION @conversationID
FROM SERVICE SenderService
TO SERVICE 'ReceiverService'
ON CONTRACT FileQueueContract;
SEND ON CONVERSATION @conversationID
MESSAGE TYPE FileIDForQueue(@fileid);
--END CONVERSATION @conversationID;
COMMIT TRANSACTION;
GO

/*
STORED PROCEDURE RESPONSIBLE FOR RETRIEVING QUEUE ITEMS IN FIFO STYLE
*/
CREATE PROC spGetFileFromQueue
@FileID INT OUTPUT
AS
RECEIVE TOP(1) @FileID = CONVERT(INT, message_body) FROM FileIDReceiverQueue
GO

/*
STORED PROCEDURE RESPONSIBLE FOR "PEEKING" INTO QUEUE
*/
CREATE PROC spPeekFileQueue
@FileID INT OUTPUT
AS
SELECT TOP(1) @FileID = CONVERT(INT, message_body) FROM FileIDReceiverQueue
WHERE message_body IS NOT NULL
GO


Now that my stored procedures are in place, I can test in TSQL:

-- to send it to the queue:
spSendFileToQueue 45

-- peek into the queue
DECLARE @F INT
EXEC spPeekFileQueue @FileID=@F OUTPUT
PRINT @F

-- to get it back
DECLARE @F INT
EXEC spGetFileFromQueue @FileID=@F OUTPUT
PRINT @F


From here it's trivial to port the procedure calls to C#:

public static void RunActionProc(string procName, SqlParameter parm) {
SqlParameter[] parms = new SqlParameter[] { parm };
RunActionProc(procName, parms);
}

public static void RunActionProc(string procName, SqlParameter[] parms)
{
SqlCommand co = new SqlCommand(procName, GetConnection(true));
co.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter parm in parms)
{
co.Parameters.Add(parm);
}
co.ExecuteNonQuery();
}


public static void Enqueue(int value)
{
DBHelper.RunActionProc("spSendFileToQueue", new SqlParameter("@FileID", value));
}

public static int Peek(){
SqlParameter fileIdParameter = new SqlParameter("@FileID", SqlDbType.Int);
fileIdParameter.Direction = ParameterDirection.Output;
DBHelper.RunActionProc("spPeekFileQueue", fileIdParameter);
return Convert.ToInt32(fileIdParameter.Value);
}

public static int Dequeue() {
SqlParameter fileIdParameter = new SqlParameter("@FileID", SqlDbType.Int);
fileIdParameter.Direction = ParameterDirection.Output;
DBHelper.RunActionProc("spGetFileFromQueue", fileIdParameter);
return Convert.ToInt32(fileIdParameter.Value);
}


A sample project in C# can be found here.

}

Saturday, February 03, 2007

The Future of Programming Languages

{

Imagine being able to pull Anders Hejlsberg, Chief Architect of C#, Herb Sutter, Architect in the C++ language design group, Erik Meijer, Architect in both VB.NET and C# language design, and a programmer's programmer, Brian Beckman into a conference room and have an hour's worth of conversation on programming languages - to hear about composability and functional programming and abstraction from people whose decisions literally shake our world from the top.

This recent video on Channel 9 is just that.

At the end, when they are getting kicked out because someone else is scheduled for the room I can't help but laugh. Guys like Anders Hejlsberg get kicked out of conference rooms too eh? They must be human.

Here are some quotes:

Anders -

"language is like the color of your glasses... "

Beckman -

"Scheme is sort of God's Lisp with all the noise boiled away..."

Meijer -

"By definition you cannot have too much abstraction because abstraction means leaving out the unnecessary detail. So if details are unnecessary you can abstract... sometimes you abstract from necessary details but that isn't true abstraction because you've taken away necessary detail"

}

IDE Distrust

{

Some time back I read Charles Petzold's essay Does Visual Studio Rot the Mind which concerned itself with some of the negative aspects of how our tools drive us rather than us driving our tools. It's not just a handful of occasions where I've been called over to "troubleshoot" when a person's intellisense (or autocompletion) isn't popping up what they are expecting.

But Visual Studio does impress upon you the wrong ideas sometimes.



In this case it will show an error for a missing mime type on a script tag. Granted, this may be some part of XHTML validation but after listening to Douglas Crockford (and also, incidentally, running into it in the Rhino book), I discovered this type attribute isn't leveraged by any existing browsers.



If you give in for the sake of XHTML and supply this attribute, you'll notice that Visual Studio suggests text/javascript which is actually incorrect. It should be application/javascript.



Here is something even more concerning - Visual Studio is suggesting two parameters for a method that actually only requires one (I looked in the Rhino book).

Visual Studio is a great tool, don't get me wrong - as much as I'd love to be an Emacs junkie and do my demonstrations in it while showing off my profficiency, I like how effecient Visual Studio is at allowing me to focus on my code - not my libraries, or my classpath, or anything else.

With that said, it's important to master the tool, as opposed to being mastered by the tool. A healthy amount of distrust seems necessary to get the best out of it.

}

Thursday, February 01, 2007

Founders At Work

{

I'm looking forward to reading Jessica Livingstone's book, Founders At Work, which consists of interviews with various techie entrepreneurs. Joel Spolsky's interview, however, is available as a freebie and makes for some interesting reading. I've been a Joel "fanboy" for a while but it still impresses me how each time he writes (or comments) at length there's so much truth from which to learn.

There are several other interviews I'm looking forward to reading, particularly Philip Greenspun's on the making (and possibly breaking) of Ars Digita. A few years ago Philip did an interview on IT Conversations that impressed a lot of "lessons learned" upon me.

But back to Joel, the interview is insightful and there are many gleanings on consulting, founding, competition, learning, and making good software.

I'll get to the Woz interview this weekend.

}