|Think about Loose Coupling|
As my recent series of posts has implied or expressed, I've been revamping some code from an earlier project of mine. Today I saw my list dwindle down to the last item: numerous (seemingly random) Dr. Watson errors that cropped up during my database calls. Unfortunately for me, this appeared to the most elusive thing of all to try and eliminate. In the end, it ended up being not-so-difficult of a thing at all; however, I don't think this was the intended behavior of ActiveState Perl. I believe it is a bug, but one that can be worked around. I could be way off on this, but you be the judge.
For those of you wanting to compare notes (or are looking for a little more background), my setup here involves Windows 2000 Professional, Apache 1.3.24 for Win32, and ActiveState Perl 126.96.36.1991.
I was noticing that the CGI script in question would occasionally call Dr. Watson. Sometimes it would occur every time when I ran the CGI repeatedly with the same parameters, and other times it would work just fine with those very same parameters. Using print() as my debugging tool (and by commenting out potentially offending code along the way), I realized that when the error occurred, it would be at some random point in a function after a prepare_cached() statement. Not realizing why this would happen, I set out to determine why.
When I first wrote this script, I knew that connecting to the database was likely going to be the most expensive part of the CGI. What I did was create a global database handle and a global statement handle that got used for each database call. While I thought when I originally designed the script I was careful to finish() a statement before prepare()ing the next, the first thing I did was check to make sure this was, in fact, still the case. When I confirmed that was not a problem, I beat my head against the wall a while longer, threw in some more print()s and some more comments, but to no avail.
On a whim, in one of the functions of my CGI, instead of using the global statement handle, I instead created a local handle. To my surprise, running the script with a set of arguments that was consistently bringing the Dr. to visit stopped calling him. Excitedly, I changed the rest of the statement handles in my script from global to local and lo and behold, all of my Dr. Watson errors went away! I have since extensively tested this script with every set of parameters I've ever known to call Dr. Watson (repeatedly tested), and the Dr. is long gone!
While I realize my original design was somewhat flawed, I don't think it was tragically so, certainly not to the extent that it should have caused me so much grief. I personally feel that it is bad behavior on ActiveState's part to allow such code to trigger Dr. Watson, but some of you might disagree.
During this time, I did some research on ActiveState's bug site, and I'm apparently not the only one getting access violations when using the DBI module. Sadly, the last time ActiveState even acknowledged such a bug was in November of 2000. According to the site, it was never resolved. There have been other such reports since then, all of which are labelled "unconfirmed."
As there appears to be no hope of seeing this fixed soon, I post my sorrows and my findings in hopes that others here who have experienced/are experiencing these problems may benefit from the time I spent on this.
If you have questions or want more information about this, please feel free to post or /msg me.