Whilst the title of this post might indicate some sort of Pirate link, I'm afraid it's actually a statement of frustration with Subversion and TortoiseSVN on Windows Vista.
I love SVN, it's really simple and clean, the TortoiseSVN shell extension for windows is also really slick, I love to use it, it is howver driving me round the twist.
On occasion I'll get errors instructing me to run a cleanup on the folders, which I'll attept to do, but that fails resulting in me being left with manually trying to clean up subversion folders from my installation.
Believe me when I say that's not the easiest thing to do, not only do you have files which are hidden from you in the shell (.svn folder for example), but when you do access them, they can't be changed as they're being access by another mystery process.
I spent a good couple of hours last night faffing about with subversion locally until I finally gave up and blew away all my local files and rebuilt the lot from the repository.
I've switched over from using .svn to _svn as the folder names to see if it makes life easier.
Checking through the TortoiseSVN documentation wasn't really much help, they claim to have fixed all known Vista bugs so either I have a broken repository or life is just making things difficult for me.
A schema in general is a specific, well-documented, and consistent plan. The related word, scheme means a loosely described plan.
The word schema comes from the Greek word "σχήμα" (skhēma), which means shape or more generally plan. The Greek plural is "σχήματα" (skhēmata).
It was a dark day in developer world. Deadlines were looming on the horizon. Clients had been promised the impossible by sales people. All that stood between victory and defeat was a DateTime.
A couple of weeks ago I had a hellish experience that I want to share with you, not so much as a learning experience, but more to help me offload my own psychological issues onto you.
I'm working with a third party provider [Name withheld] who have a very well documented API for accessing their systems, I'd built a library around the schema they have defined as well as their API's to help me deliver the solution I was building, everything was going swimmingly well.
Everything was going so well in fact that I built and delivered the system in record time; a matter of hours. Smiles all round.
We deployed the product and showed it to the clients who were more than impressed, things could not really get any better. We continued to show off our amazing product to clients until that fateful day, the day when one part of the system stopped working, the day when I was showing off the system to the entire company, in front of everyone, the system failed.
Now, this is nothing new, "it works on my PC" syndrome you might think, alas, if only it were that simple, this system is built to ensure the safety of remote workers in very dangerous environments, failure of the system is really not an option. My reputation in front of this company was shattered. I was distraught.
Immediately I sat down at my PC and started to debug the application, what on earth could it be that was causing such a catastrophic failure? I stepped through the code line by line, everything seemed to work fine, I ran all of my unit tests even the ones which inferred test data from the schemas provided by the third party, everything passed. I was at a loss.
I was clutching at straws and trying to blame anything as long as it wasn't my code. It occurred to me that there was one part of the system my tests weren't covering, the actual data I was being sent by the third party system, not what their Schema said I should receive, but rather the data it's self. It couldn't be that though surely.
Ah ha! On closer inspection, it was a line of code, something very simple, that was the source of the problem. Here is the line (as it was): -
DateTime Received = Convert.ToDateTime(DateTimeValueFromThirdParty);
Now, my code had worked earlier in the month fine, so I jumped to the natural conclusion, the code is running on a server here in the UK, set to run with a British Culture; it must be a UK/US date format issue! (For those of you who don't know, US date format is MM/dd/yyyy and British date format is dd/MM/yyyy). Whilst 10/04/2007 would work fine both in the UK and the US, 10/14/2007 certainly would not.
With this in mind I wrote an e-mail to the third party provider asking for their confirmation on the format their dates should arrive in. My suspicions were confirmed, the dates were in a US format: -
"All of the dates in our current XML schema are in 'mm/dd/yyyy hh:mm:ss' format"
No problem, The .NET code should have worked but it didn't want to, I will just use the ParseExact method of the DateTime class to grab exactly the right format, there's obviously something screwy going on! So, off I went, my little developer hands tapping away at the keys and I changed my line of code into this masterpiece: -
DateTime Received = DateTime.ParseExact(DateTimeValueFromThirdParty, "MM/dd/yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
I deployed the site (a long process involving build scripts and database synchronization don't you know!), fired up the interface, clicked all the right buttons, expecting a rapturous angelic chorus, but no, the application had different ideas, all I heard was a raspberry. To say I was not best pleased would only come vaguely close to my feelings at the time.
The code was checked, checked again and then checked a third time, there was NOTHING wrong with it.
As I sat sobbing, a flash of inspiration hit me, perhaps it wasn't my code at all, but the data its self! Now, this wasn't so easy to check, the code that was failing has no UI, in fact it get's called by another external system which also has no UI, so the only way I could check the data being sent to me was to log it somewhere, I opted for e-mail and duly wrote and deployed a modification to the code which meant the raw message from the third party provider would be e-mailed to my own inbox, rather ingenious I thought.
After the pressing of buttons and whirring of machines my inbox exploded with content. Here was the payload ready for me to inspect, with care, I teased open the mail message, peeking inside at the content, what do I spy?
"Bastards" I uttered as I read and re-read this e-mail in sheer awe. I'd spent hours trying to track down this issue. In front of the entire staff of a company, my own application had failed, I was battered and bruised. There, nestling inside it's snug little XML jacket was a DateTime, not in the format specified, rather, well, words cannot express what I found, so here's what I found, this, this, MONSTROSITY: -
04/24/2007 10:27:18 PM
PM?? P bloody M ??? Oh I am sorry Mr DateTime, by all means, you just make it up as you go along, that's okay.
I walked away.
I had a cup of tea.
I mumbled expletives under my breath.
I had another cup of tea.
Then I penned an e-mail. My anger had ebbed away by that point and all I was left with was a bitter taste in my mouth (too much tea perhaps?). I responded to the original mail which said "All of the dates in our current XML schema are in 'mm/dd/yyyy hh:mm:ss' format", I wanted to be sure to keep the context.
In my e-mail I included a code sample explaining that the DateTime format being sent was in fact "MM/dd/yyyy h:mm:ss tt", and not as had been earlier stipulated "MM/dd/yyyy hh:mm:ss".
In response I'd expected some form of explanation, alas, that was not to be: -
I would think that your should use the format string "MM/dd/yyyy hh:mm:ss" with the DateTime.ParseExact method, rather than "MM/dd/yyyy h:mm:ss tt".
Our dates contain hours in two-digit 24-hour clock format and therefore no AM/PM specifier. Your code attempts to parse the value as containing hours in either one- or two-digit 12-hour clock format with a trailing AM/PM specifier. This may chance to work in some cases, e.g. between the hours of 1am and noon, but is not likely to be reliable, particularly when using ParseExact rather than Parse.
You would think it would use the Format in the Schema, that might well be an informed decision to make, it was certainly the one I'd made initially. Funny how what you think reality should be and what reality actually is are often at odds with one another isn't it?
I responded to this latest installment so that I might further clarify my predicament: -
"I've just spent an interesting evening hunting down an error with this, the date format is actually slightly different: -
04/24/2007 10:27:18 PM
Note it's using a 12 hour clock and including a PM/AM indicator."
Shortly after sending this e-mail a Lump of coal was shoveled into a furnace, the heat from that furnace blasted against the side of a tank filled with water, some of that water heated to above 100 degrees and rose up inside the tank in a gaseous form, it hurtled down a series of tubes and into the path of a rather quickly spinning turbine, that turbine was attached to a generator, this sparked into life and fired an electrical current through a wire along the country side and down to a small tungsten light bulb, finally, someone had a flash of inspiration and a lightbulb appeared above their head.
Back came this e-mail (accompanied by Angelic Chorus): -
"That's interesting and flies in the face of what I had previously believed. I will look into why this date format differs from our others, but since it is that way and presumably always has been we will not seek to bring it into line with the rest of the system."
Sorted, the format was fixed, I could move off this project and back onto the new exciting work I was due to begin.
That feeling was very short lived, less than 12 hours later I received a phone call which told me that the product had stopped working again, I assumed user error and rather arrogantly pressed the buttons and flicked the switches only to watch the whole system collapse in on it's self. Again.
On inspecting the payloads (I'd left my debug code in there) I was somewhat perturbed to find this little nugget of loveliness waiting for me: -
The more observant of you will have by this point noticed the lack of AM/PM indicator and the leading 0 on the hour. How nice, the DateTime has shifted format, again. By this point I'd actually taken the ParseExact format string and moved it into a configuration file, perhaps I can predict the future, but I just wasn't feeling too confidant that the format would remain as I has been told it would.
I made a quick phone call to one of the developers at the third party and he confirmed the format had been changed, again, and that it was at fault, shortly after I received an e-mail which contained this explanation (as well as some other information I had asked about): -
"The date format always should have been, and will remain, 'MM/dd/yyyy HH:mm:ss', in line with the general rule that applies throughout our XML schema. The recent change was in fact due to a bug fix which, whilst it corrected the format, was actually made to ensure consistency in the date value. It just so happened that the incorrect value assigned to the date before the fix also resulted in its being in an incorrect format."
So there you have it. If you're going to patch something, you'll probably break something else. I'm sure Mr Stopford of MBUnit fame would remind me of the place of Unit Tests in your development process at this point.
Now, I can't fault the third party in question, they were very responsive to all of my questions and queries, they apologized for all the inconveniences caused and the system has worked flawlessly since. They have a very good customer service department and their developers are both hugely competent and very approachable. All in all, they're a good partner to work with. This post isn't about them, but rather my blind faith in the Schema.
I had wondered if starting this blog post with a definition would be a tad snobby, but in retrospect, it seems to punctuate this post quite nicely. A schema in general is a specific, well-documented and consistent plan, but remember, sometimes, it's just wishful thinking.