Arrrrr! Cap’n Eric be learnin’ about threadin’ the harrrrd way

Avast ye scurvy dogs, it be National Talk Like A Pirate Day!

A scurvy bilge rat commented on the preceding discussion about putting apartment threaded objects in Session scope:

Back in the era of the NT4 Option Pack I wrote a lot of code that involved stashing Scripting.Dictionary objects in both session and application scope. […] I forget now which version of the runtime changed the threading model they were registered with and broke everything for me.

Shiver me timbers! That be my fault. Sorry about that.

When you create an ActiveX object, the COM runtime code checks the registry to see if the object is marked as participating in the Apartment, Free or Both threading models.  We’ll go into the difference between Free and Both at another time.

(UPDATE: I don’t believe I ever did.)

Now, when I was a young swabbie seven years ago I was given the task of implementing the Scripting.Dictionary object, and I didn’t yet understand all the stuff I just told you maties about threading.  In one build that was released to the public I accidentally marked the dictionary as Both, even though it is a Single Threaded Apartment object. So when lubbers would put a dictionary into Session scope, it would be called by multiple threads at multiple times, in violation of the apartment contract.  As long as there were only readers, it was generally OK, but as soon as there were readers and writers, it would usually crash and die.

And of course when we corrected the mistake, all those pages went from sometimes-crashing-but-fast to not-crashing-but-slow. That was my first majorly customer-impacting mistake, and probably the worst I ever personally made.

(UPDATE: Surely I have made worse since, but it really was very bad. Our code review protocols were not strong in those days. More on that below.)

Speaking of mistakes, there was another interesting performance mistake in early releases of the Scripting.Dictionary object. It uses a very simple hash table for rapid lookup, but of course hash tables require that the hash function distribute hashes broadly given a narrow distribution of keys.  I screwed up the hash algorithm, and one of the consequences was that hashing on a string consisting of five digits was likely to go to a very small number of hash buckets.

We discovered all this the day that decided to store every zip code in the United States in a Scripting.Dictionary object in Session scope!  Perf of went way south, way fast.

The combination of the two mistakes above led the ASP team to write their own string table object, that really was Both threaded and blindingly fast. Arr!

There was a lot of good reader response to this article, and a number of commenters went with the silly pirate theme:

So yer the bilge rat who caused that! I meant to ask you about it, arrr. To this day I be not using dictionary object because of a bad experience with it building some scurvy shopping carts.

When I boarded Microsoft a few years back for some Commerce Server demos, I asked a mate there about that bug (and if it still existed). He was most scurvy in his reply. Yarrr.

By the way, why was On Error Goto 0 not documented in earlier versions VBScript? Some lubber VB developer suggested that I try it, and I was very surprised back then that it worked. Were there any other undocumented scurvy features like that? What about easter eggs? Aarr.

Arr, you have to keep in mind that the VBScript documentation “team” at the time was one guy. Actually, not even one guy — Fred spent some time documenting other stuff as well I believe. Now, don’t get me wrong — Fred was a great guy, a lot of fun to work with, and very competent. But there simply was not enough time, budget and manpower to do a really proper job on the script engine documentation. A few things fell through the cracks now and then.

Documentation is extremely expensive. Writing it the first time is not so bad. Translating every page into 26 languages, that gets real expensive real fast.

Arrr! Havin’ spilled the beans, swabby, you best be protectin’ ye precious cannon balls from enemy swords. Many a tall ship crashed on the rocks of the Scripting.Dictionary. Aye, she was a most gnarly beast, for sure.

So, how did a green eared bilge monkey (I mean that in the nicest piratey way) like you come to possess the Scripting.Dictionary beast with nary a review by a superior officer? The captain must surely have been afire that day with many unruly mates on the plank, no?

Well, bygones begone, mate! Let’s heave a pint with a merry yo ho to brave Lippert’s mighty confession this day!

Arr, we certainly had code reviews, but the script team in the early days was pretty cowboyish.

The dictionary object shared its registration code with an object that really was Both threaded, and that fact led to the defect. In that situation even experienced code reviewers fall into the trap of “this code has been reviewed before, we can skip reviewing it this time.” As time went on we became more and more hard core about reviewing every line of every change.

ARR! So ye be the scurvy squad what made yon Dictionary object walk th’ plank! If I was a younger man, I’d a’ strung ya up and keelhauled ye afterwards!

Seriously, though — as much of a mistake that was, it’s good to see that you’re willing to owe up to it. It’s probably not proof against making an even bigger and more far-reaching mistake, but it also says a lot about the caliber of person you are.

Have you yourself ever used any third-party components to replace the Dictionary object, that are also thread-safe? And if so, which one(s)?

As I mentioned in the original article, the ASP team wrote their own “lookup table component”, which you used to be able to download from their site. I have no idea where it is now though.



1 thought on “Arrrrr! Cap’n Eric be learnin’ about threadin’ the harrrrd way

  1. Pingback: Porting old posts, part 1 | Fabulous adventures in coding

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s