Archive for June, 2006
Last Thursday night, I met Sean and some friends out at PK's for pizza. As we ate, I heard Counting Crow's "Mr. Jones" come on the jukebox behind the sounds of chatty crowds and the clank of billiard balls. I focused on the music, the other distractions fading away, and as I always do when I encounter Counting Crows, I thought about Jeremy Turner.
I remembered HFStival 1994 when Jeremy and I were watching the band perform. The crowd was very enthusiatic and swaying back and forth to the songs."Wait a second," I said, "My feet aren't touching the ground!"
"Mine either!" Jeremy laughed.
It was a disconcerting feeling for me– to be moving about with no control. "I don't like this," I said, "Let's get out of here."
"Okay!" Jeremy said.
A few minutes passed and we were still in the same predictament. It turns out it is quite difficult to leave when you're feet aren't touching the ground! 🙂
- A cappella Round Here
But mostly, I thought of the times were Jeremy would sing just for the sake of singing. One evening in particular, I remember a group of us walking down a road in the late, late evening. Out of nowhere, Jeremy sung Round Here from start to finish, accompanied only by the sounds of summer insects and the darkness of the night. It is that rendition that remains my favorite (even over the original) and that rendition I will always recall.
Back at PKs, someone started to talk to me and my attention returned to the present.
"You're thinking of Jeremy," Sean said, matter of factly.
I had to smile. Sean has never met Jeremy Turner and in fact, I haven't seen or heard from Jeremy in nearly a decade. But Sean knew. From all my stories, my own oral traditions, Sean knew exactly what I was thinking.
I think one of the ongoing challenges of being a software developer is the blurred lines between your product and the technologies that compliment or are used by your product. That blurry border can often impact the impression of your work.
With QualTrax, a feature of the Document Control module is that it doesn't restrict what kind of file format you use– it will accept and control all kinds of documents. Because of that flexibility we don't provide our own proprietary editor. Instead we rely on the applications that are already targeted and fine-tuned for that file format, the same applications the users are already accustomed to working with. For example, the engineering department can continue to use AutoCAD to update their DWG files. Human Resources may utilize Microsoft Word or Microsoft FrontPage to maintain their Employee Manual. Meanwhile other departments can continue to use Visio or ABC Flowcharter to upkeep their process maps.
Well, a downside of that flexibility is often when a user experiences an issue in their editing application (Microsoft Word for example) — they don't draw a distinction between that application and QualTrax. From their perspective, all they know is they are having trouble doing what they need to do. Their struggle may just be a usage question like "How do I make this 'X of Y pages' bigger in the header of my Word document?" or it could be something that is directly related to a change or bug in the editing application. A good (though old) example would be the Office 2000 release. In that initial release, suddenly any Office 2000 document opened within Internet Explorer triggered a password prompt. It was a Microsoft bug and it was rectified by Microsoft in Office 2000 Service Release 1. Nonetheless, it was easy for a customer to get annoyed and think, "QualTrax is always asking me for a password."
Third Party Controls
The waters are even muddier when it comes to the third-party controls you integrate into your software. Unfortunately, I recently ran into an example with the RichTextBox control. For this particular project, we were modifying a pre-existing web application to create a similar version for a different use. In the original application, the RichTextBox control was a perfect fit and did its job well. No complaints. But when we went to deploy the new application, we had a series of complications.
- First, the new web server was using ASP.NET 2.0. ASP.NET 2.0 shipped with a new security feature, allowing Trust Levels to be set on a by-application basis. The RichTextBox control required a Full Trust Level, but the web server being used was locked down to only permit Medium.
- After we got over that hurdle, persistent popup messages were reminding us to purchase the component.
- Once the purchase was made, the customer reported a series of issues with using the control. It turns out in the original application, the requirements of the component were pretty standard– bolding and formatting text, maybe the occasional italic here and there. The new customer was using tables heavily and through that usage, revealed difficulties.
- You couldn't size tables by percentages; you had to use pixel count.
- It wasn't intuitive how to resize the individual table cells.
- Originally there was confusion as to how to align the text in a table cell (though that does appear to work well).
- Further compounding the other issues, the RichTextBox control wasn't always refreshing its view. That meant a user could be resizing a table cell, but not see the changes applied to the screen and therefore did not have adequate feedback to know they were successful.
Now don't get me wrong, there were other hiccups with the system. But they were few and far between– a vast majority of the issues and frustrations arose from that one control.
Unfortunately, the customer's keen eye is not likely to isolate the control as the culprit. It is the system that is deemed buggy. Even though I, the developer, know the root cause, "buggy" is a label that still stings. In the customer mind, there is no separation between the controls you use and the system.
Best Practices Thus Far
In the RichTextBox example, I can be smug and think about how I did not pick that control (I can report "buggy" still hurts though!). But for the controls we are empowered to pick, it's extremely important when evaluating them to keep in mind that their performance and reputation directly affects yours.
At QualTrax, we pay significant note to the controls we include. In fact, we have a dedicated Evaluating and Purchasing Third Party Controls procedure (falls under ISO 9000:2000 7.4.1 Purchasing Process) outlining our decision criteria. We, of course, look at the threading model, the cost and the scalability of the component. A couple of additional items we consider include:
- Pre-Installation Requirements – What other components and software does this component need? How will that effect QualTrax's Pre-Installation System Requirements. Our customers work over a variety of databases, platforms and languages. We by no means want to alienate a customer by adding a control that means they can no longer use a feature.
- Deployment – How hard will it be to deploy the new component in the QualTrax CD Install? Are there any specific permission needs? It's been our experience that IT Administrators aren't quite thrilled with notion of the anonymous web access user being an administrative account. If that's something the control requires, it is certainly going to drop in our favor.
- Responsiveness of the Support Team – This is key. We've already established customer perception is tricky. If an issue arises with the component, it's going to be deemed a "QualTrax" issue. In the event that happens and we have to rely on the support team of the vendor, how effective and fast is that team? If it takes the vendor three weeks (not to mention a lot of prodding) to get an answer to us, imagine the response time we'd have to our customers. Once during an evaluation period, I had to email a vendor's support staff a question. By the time that company sent back their first response to me a week later, the content of their answer made no difference. I already knew they weren't the vendor for us.
In addition to those considerations, any component we implement in the software goes through a detailed feature-specific testing process on our varied platforms and with the same rigor we give our FDA 21 CFR Part 11 testing. When we replaced SAFileUp with aspSmartUpload (for pricing considerations, not performance), the test script covered a variety of browsers including Safari, Internet Explorer, Netscape and FireFox. The test script even specifically called for the download of files that had Japanese characters in the title.
Leveraging Advantage Through Support
Despite one's best efforts in component and technology selection, with all the different customers, their different configurations, their different permission sets, their different usages and different levels of expertise, a question or an issue is eventually going to arise.
Although the difference between our application and other applications is very clear to us, it is our practice in QualTrax to assist with everything we can. We are aware of and sensitive to the customer's perception and that's what we act on. If it turns out to be a situation that needs to be expedited up to Microsoft, Adobe, Oracle or some other organization, we will help the customer in that effort as well– participating in conference calls or serving to "translate" the nature of the problem.
And suddenly the blurry line of what's yours and what's not can become an advantage. From the customer's vantage point, you're not fixing Word or Internet Explorer or Visio or SQL Server or AutoCAD; you're fixing the problem. Even if you are troubleshooting an outside technology– if you solve the customer's issue – you are just as much of a hero as you would be if you corrected your own code.
And what's the customer perception when it's all said and done? That your team is the place to go for a resolution.
I have an example for that as well! About a year ago, one of our customers made an update to his server that broke all his web-based applications, including QualTrax. Out of all the vendors, he called us first. He said he knew we would be the ones who would fix the problem quickly. His faith was well placed that day – we didn't let him down!
So in the customer's mind, you are indeed the technology you use.
But how you choose to handle those perceptions… could very well trump all.
In 1866, a German man by the name of Ernst Haeckel developed a theory called "Recapitulation". He proposed that as it developed, an embryo would pass through forms of its evolutionary ancestors; it would "recap" the development of the species so far. According to Haeckel, as a human embryo developed, it would phase through the form of a fish, then a lizard, then a chicken, then a monkey before finishing at human. So each time a new life was conceived, the evolutionary process would supposedly play itself out again in the closed venue of the womb.
Well, as it turns out Haeckel's findings have been long disproven and his credibility shattered! Recapitulation has no place in modern biology. But could the concept still be alive and well in programming?
I've been working on writing the QualTrax Document Control Engine in .NET. It struck me today that my efforts have had some similiarity to QualTrax's past feature progression! In some cases I started off with the base features– the features that existed way back in 1997 in Version 2.3 and then moved on to finalize the later features. For example:
- I started with the basic Document class and then I worked on approval routing. After basic approval was working, my efforts turned to ensuring Serial Approval (introduced in 2002) was working.
- When QualTrax was originally released, HTM was the most popular document format. Unconsciously, I completed with the HTML Automation and Automatic Link Conversion features before moving on to Word Headers and Footers (introduced in 2003) and then finally to PDF Conversion (introduced in 2004).
- Once the document lifecycle was working, I tackled the Document Compare Add-On Tool (introduced in 2004) and the Out of Office Manager (introduced in 2004).
Unfortunately, like Haeckel, my findings have some flaws:
- Yeah…I probably was not following the evolutionary path of QualTrax features. Be it an embryo or a program, you have to develop the backbone early on– your framework for everything to follow. In QualTrax's case, the backbone of Document Control just so happened to be included with the core product from the very beginning.
- I can say I did Serial Approval after regular Parallel Approval– but in fact, the database and backend code were done concurrently. I just didn't happen to focus on and test serial approval until after I knew the base was working. 😉
- And the biggest flaw of all! Before even the Document Control Lifecycle was approached, Folder Specific Settings was fully complete. Folder Specific Settings post-dates all of the other features I mentioned tonight– it wasn't introduced until June of 2005! Not only that, but brand new settings (PDF Security Settings) were added- all before the first Document Revision was ever started in the new system.
Well… it was an interesting thought to explore nonetheless! 🙂
Last night the Cure Cancer Soon (aka CCS) participated in their 4th Relay for Life. I was there from about 7:30 PM to about 6:00 AM. During that time, I totaled 60 laps which is 15 miles.
Earlier in day, I didn't feel up for the relay and lamented how time passed so quickly and how I was tired and how I wanted to rest at home and yada yada yada. But as soon as I arrived at the venue, the energy of the event caught me and I wasn't about to leave for anything. In the hustle and bustle of daily duties it is easy for me to forget:
I love Relay for Life.
I love how in the early evening, you see children and adults playing– throwing footballs and frisbees, hula hooping or just plain goofing off. I saw one little boy running around on all fours barking and pretending to be a dog. Simple pleasures. Everyone is out enjoying the weather and visiting. It's a reminder of how communities can be.
I love how moving the luminary service is– even after you've experienced it in the years before.
I love getting to know some of my co-workers better. I have worked with some of them for years– but since we are different departments, we don't really get to know each other.
I love walking and talking with people. It's not a luxury I get when I walk with the dogs. 🙂 It reminds me of the walks I've taken with my mother or grandmother.
I love the Mr. Relay pageant. I almost didn't watch this year, thinking been there done that. But still, no matter what, no matter how many times I've seen a man in a stuffed bra and silly wig shake his ass seductively to the audience, I crack up aloud. I also love how there is always one contestant who is so convincing you can see some people in the audience shifting uncomfortably. And, of course, I love that somehow year after year, teams find a man secure enough to volunteer to participate in the pageant.
I love that we stay up until the sun rises and we talk and tell stories and play trivia and laugh. It's nostalgic for me– that's what my friends and I used to do before we all turned 21. Here, for one evening, we can have a blast with just each other's company and the fresh air. I love that.
And finally, I love that I get to have all that fun– while helping out a good cause! 🙂
On Thursday evening I babysat young Gwyn (1 1/2 years old) and Penn (4 years old). I got to change my first poopy diaper, which turned out not to be an ordeal at all. I suppose the steady exposure to various animal accidents had to pay off sometime. The only bump in the road came when little Gwyn needed to go to bed. She was a bit unhappy with the notion and a lot of crying was to be had.
"I know!" Penn said and disappeared to his room. He emerged carrying one of his precious teddy bears– the ones he never shares. It was a very big move for the boy.
I couldn't help but be touched by Penn's generosity. As he reached over crib and put it into his sister's suddenly calm and content arms, Penn looked at me and said:
"It has pee pee on it, but Gwynie won't care."
Suddenly his philanthropy made sense.
We have a class library that reads from a custom .config file— aptly named qualtrax.config. One of the first things we do in that class library when we are retrieving a setting is verifying the file exists. It’s a simple call something like:
//Our Error Handling
Because we are not specifying a directory, it is checking for the file in the current directory. With debugging in our test Windows application, this “current directory” is pretty intuitive. It’s looking for the qualtrax.config file in the \bin\Debug folder.
When we started using the library in an ASP.NET application, however, the expected location of the qualtrax.config file was not as intuitive.
Right off the bat, it was not able to find the file. So I copied it into the website root so it sat side by side with web.config. Still the file could not be found. I put it in the bin directory. No luck. App_Data directory. No cigar. We knew it wasn’t permission errors because when Derek hardcoded the path, it was able to read the file just fine. We just didn’t what directory it was trying to look into by default.
I was about to embark on a pretty inefficient journey when Derek said, “I’ve been meaning to try using filemon to see where it is looking.”
So it was FileMon to the rescue. We installed it and turned on capture right before our System.File.IO.File.Exists call and then checked the log.
353 4:12:26 PM aspnet_wp.exe:5412 QUERY INFORMATION C:\WINDOWS\system32\qualtrax.config NOT FOUND Attributes: Error
This won’t be the end of our efforts on the matter, but there are two morals of the story thus far:
1) If you are doing a File.Exists call in an ASP.NET application without specifying an explicit directory and things seem to be missing– it very well may be looking in the Windows\System32 directory! 🙂
2) FileMon proves time and time again to be a very valuable troubleshooting tool. In the past, we’ve found it especially helpful with permission problems. Shame on me for not thinking of it sooner.
In civilizations where citizens did not have ample access to a writing system, history and stories were passed down orally in the form of repeated tales and passages. It is thought that Homer's Odyssey actually pre-existed its written form for sometime being recited and tweaked by poets. The Gospels in the Bible are pretty readily accepted as being written nearly a century after the crucifixion, a generation after the original followers. As a more contemporary example, the powerful stories in Roots were passed down verbally to each new generation all the way down to Alex Haley.
Well in our modern times, where 30 million people have blogs, you can still see subtle signs of oral traditions still in action. This week, I saw at least two examples:
I got to watch two of our newest account managers perform their QualTrax demos. During their presentations, I could catch snippets here and there that I could attribute to different sources– other account managers, our training coordinator and even a passage on ISO 9000 Standards that was almost verbatim the way I describe it. Most interestingly, there were phrases that I use that I have not yet uttered in front of these two presenters, but I had to their teachers and their peers. And some of those phrases likely originated from my predecessors!
So just like the ancient epics, the QualTrax demo includes repeated "verses" and the influences of the past "poets"…yet still has the unique touch and perspective of the current orator.
Abled-Body Young Man
Story-telling is a favorite activity of my extended family, myself included. This weekend I had the opportunity to retell the story of when my brother, Jay, was watching my grandfather who was pretty elderly at the time– roughly 92-93 years of age.
At one point Grandpa lamented about how he could no longer go to church.
"I used to go to church every Sunday," he said, "But now I'm too old and Mother can't take me."
"Well," my brother thought, "I'm an abled-bodied young man, I can take him to church."
"Grandpa, do you want to go to church tomorrow? I'll take you!" Jay said.
"Oh no, no," Grandpa said, "I'm too old. I can't go to church anymore. I'm too old."
Jay waited a few seconds, then he posed another question.
"Grandpa, do you want to go to McDonald's tomorrow? I can take you."
"Oh yeah!" Grandpa said, "Let's go to McDonald's!!!"
Now, as can be expected, any good story of mine (well one I think is good anyhow–I've been known to misjudge), poor Sean has already heard dozens and dozens of times. So it is understandable when he is less than enthused with my repetition. However, his reaction to this particular tale seems to trump the others.
"I just know you are coming to the part where you say 'abled-body young man'" Sean once explained, "I know it's coming. There's no escaping it. You always say that!"
He's right! I do always say that and actually, consciously so– that's the way my brother relayed the line to me.
I'm just passing it on! 🙂