The Third (Party) Circle of Hell
While Ian was working at Initech, one of the major projects he undertook was an integration with a third-party vendor. They had recently gotten set up with this product that became known internally as the Third Circle of Hell (3CoH), and wanted to export some data from it over to the vendor's website. Sales agents needed some information during cold calls, and 3CoH promised to provide the data interactively, so that they could continue their call somewhat intelligently.
Getting in to the 3CoH might be easy, but getting out is another matter.
The existing system was manual and thus slow and rife with error. Sales agents would have to copy all of a customer's information, by hand, from 3CoH into a web form, which boiled down to a lot of copying and pasting. But since the vendor provided a SOAP API and 3CoH had its touted scripting language (essentially Java with some syntactic sugar for querying the 3CoH database), there was probably a way to automate the process. The task of doing that was assigned to Ian.
Of course, going directly from 3CoH to the vendor was out of the question, as it would involve hand-crafting a SOAP request and filling in fields by just concatenating together a giant string of XML with some variables. Some of his predecessor PHP developers at the company had thought that was a perfectly fine thing to do, and had created some scripts to employ that anti-pattern.
Ian had a less fragile idea in mind. With the aid of a Java library that generated Java classes from a WSDL, he set up a bridge server to stand between 3CoH and the vendor. 3CoH would package up all the needed information into JSON and send it to the bridge server. The bridge server would shuffle the data from the incoming JSON into the objects representing the SOAP request, generate the SOAP request, and send it off. When the reply came back, the process would go in reverse; the bridge server would pull out the URL returned by the vendor, and send it back to 3CoH as a regular HTTP response.
After a few development iterations, it worked, albeit slowly. That is, it would take about 30 seconds for the whole process, which is a long time when you're on a cold-call with a customer. Even worse, it would make Chrome assume the page had frozen and pop up a scary-looking dialog box to that effect. Ian was testing by pointing to the vendor's QA website and not the real one, so he naturally assumed this was the cause of the slowdown.
He was wrong.
Once they went live, he found that it was still just as slow, and the sales agents and managers were not happy, summarily resulting in various high-level managers alternately panicking about a failed project and spewing brimstone and fire down his neck about getting it fixed.
But the surprise came when Ian timed each segment:
Full Process
(3CoH -> Bridge -> Vendor -> Bridge -> 3CoH):31 seconds 3CoH -> Bridge: 1 second Bridge -> Vendor -> Bridge: 5 seconds Bridge -> 3CoH: 25 seconds(!)
Amazingly enough it was neither the huge block of JSON, nor the massive SOAP request that was the slowest part of the loop; it was the tiny HTTP response containing nothing more than a 200 for the status code and a URL in its body. After a few repetitions of the test to ensure that this wasn't a fluke, Ian had verified that his timing measurements were correct, that he hadn't gone insane, and that perhaps he had fallen into the 4CoH. He directed a few expletives in the direction of the authors of 3CoH, and Googled around. He found nothing and had to fall back on the last resort of the desperate programmer: Reckless Experimentation.
What if I sent a code other than 200? Still slow.
What if I removed https:// from the beginning? Still slow.
What if I returned something other than a URL? Still slow.
What if I returned a blank string? Still slow.
What if I put the URL into a header and sent a 309 redirect instead? ...instantaneous!
As it turned out, having a body element present in the HTTP request, in any shape or form, even an empty one, would cause 3CoH to block it at the gate, presumably for customs, interrogation or a full-cavity search, and then for no apparent reason other than to be annoying, delay about 25 seconds before continuing code execution.
But there was a saving grace; it would ignore the headers! Thus the return values could be stuffed into the header instead, and it would happily send the HTTP response, with no body, on its way and resume the script.
In the end, the other developers found this a source of great mirth. Thanks to his descent into the 3CoH, Ian died a little on the inside. But the integration was up and running.
Ian made sure to leave a long, detailed series of comments so that his successors in the 3CoH would know exactly why they could never, ever, under any circumstances return data in the message body.
[Advertisement] Release!is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!