Agnes called me over because she’d spent the last two hours banging her head against CONF-10035. Apparently, when editing a particular page on the Atlassian extranet, going to preview mode caused all the images and links on the page to be broken links. When the page was saved, though, everything worked fine.
One of the advantages of being the Architect is that by the time you’re called in to help with a problem, someone else has already done the important but boring parts of trouble-shooting. Agnes had already copied the page and all its attachments to her test environment, and was unable to reproduce the bug locally.
So I started thinking to myself. “It’s got to be something weird, or Agnes would have worked it out already. What’s different between the test environment and the extranet?”
Confluence’s database objects are all identified by a 64 bit primary key. This was a piece of deliberate overkill that comes down to never, ever wanting to have one of those “we thought 640k was enough!” moments as we explained to some fifteen-year Confluence customer that they just couldn’t fit any more content into their server.
Sane Confluence servers are unlikely to ever make use of all that key-space, but it’s good to have a ludicrously large buffer to play with. On the other hand, when the Great Bit Shortage of 2020 hits, Confluence will have to put up its hand as one of the culprits.
The Atlassian extranet has been running since the earliest days of Confluence development. It has been afflicted with every piece of dodgy alpha code we’ve felt like deploying. Extranet has never been a sane Confluence server. Some time in the depths of history, some bug crept in that bumped the database keys up well above the 32 bit limit, and there they have stayed ever since.
Back to the Problem
(To add to the confusion, Opera handles this number fine, as does Java when you convert between the
But That’s Not All
var contentId = #if ($pageId.toString() == '0') $draft.id #else $pageId #end;
var contentId = #if ($pageId.toString() == '0') "$draft.id" #else "$pageId" #end;
I think my favourite kind of problems are the ones that take hours to find, and one line of code to fix. There’s something very satisfying about it.
A man’s car has been making a very scary grinding-metal noise, so he takes it to the garage. The mechanic walks over, pops the hood, revs the engine a few times, and scratches his chin. Then he walks over to his work-bench and picks up a small rubber mallet. He gives something in the engine a hard whack, and suddenly the grinding noise has gone completely.
The mechanic walks over to the driver. “That’ll be a hundred and twenty bucks, thanks.”
“You’ve got to be kidding! All you did was hit it with a hammer! I’m not paying.”
The mechanic walks back to his bench, grabs a pad and pen, and writes the driver an invoice:
Hitting the engine with a hammer: $0.05
Knowing where to hit it: $119.95
1 Dive into Python has a good summary of the difference between Strong/Weak typing and Static/Dynamic typing, although I’d phrase it differently.