Apr 24 2008
I recently created an ASP.NET application for receiving online orders for a printing company. The web form would collect information about the company placing the order, instructions for how the job will be printed and completed (binding, etc.), delivery information, due time, and the type of file(s) that will be uploaded.
Uploads with a Progress Bar
The file uploads use NeatUpload by Brettle Development. These are open source controls which give a progress bar for uploading files and also allow multiple files for upload. Brettle’s tools rival commercial ones that cost hundreds of dollars and are highly customizable.
The entire project seemed very simple and straightforward. A work order is produced in XFDF format which populates a pre-made PDF document. An XML file containing all of the information from the work order is created for upload into a job management application that is currently being developed for the company.
Murphy’s Law in Full Effect
The work order and uploaded files were saved in a folder where the name was based on date, time, and a three digit number (the folder name is also used as the work order number). This produced a large string which seemed highly unlikely to create conflicts. If two orders were placed at the same time, there would be a 1 in 1000 chance of a collision. This was considered a highly unlikely occurrence so it was decided that I shouldn’t spend the time in writing code for collision avoidance, i.e. preventing a second work order trying to write to an existing folder of another work order.
I completed the code, uploaded it to the server, and it went live. Within a few hours, the impossible happened. Two orders were placed at the same time and they generated the same work order number. The end result was the second order overwrote the previous order’s files, except for the uploaded files.
This event caused great confusion. The first customer had to be contacted in order to place their order again. Fortunately, e-mail confirmations for every order is sent to the printer’s preflight department which is why they were able to discover the problem.
In order to prevent similar events from occurring in the future, I wrote code to prevent folder name collisions. It only took about 10 minutes to write and all that it does is checks if the order number generated matches an existing folder. If it does, then a new order number is generated.
A very simple solution.
What was learned here? Never make assumptions. Just because an event is highly unlikely to occur doesn’t means that its impossible. Someone wins a lottery despite the overwhelming odds against them. You really need to seriously look at the probability of a collision occurring. If its astronomically high, then it probably won’t be necessary to write collision avoidance code. Of course, you need to take into consideration what would happen if a collision did occur. If the outcome was serious, then it should be prevented with proper safeguards. I would say that a customer losing the work order can be considered a serious problem.
Its always important to put your customer first and place yourselves in their shoes. After all, your code is supposed to make their jobs easier and more efficient. Good code brings customer confidence and more work from them and their referrals.