Or, when is performing request-response communication over an asynchronous channel a good idea? When is it not?
If system A needs to ask system B a question and get some data as a response it could do so in a variety of ways, some awful, others less so.
- Take a periodic database extract, transform and load
- Query the other system’s database on the fly
- Use RMI / Corba binary interop
- Send a message and wait for a reply
- Get some XML from a URL via HTTP
This list is not exhaustive, but represents a reasonable spread of mechanisms. Lets narrow it down to the two least awful.
First, any integration involving a database is right out. Coupling application databases together is extremely awful. Binary integration is bad for the same reason. These integration mechanisms are fragile and make the job of releasing both applications much harder, as well as making it hard to know if a change has broken the integration.
Moving on to the two remaining choices. Using messaging can work well if the requesting system can tolerate a large variation in latency and/or you need to scale by having multiple processes sending and receiving the messages. It is also very handy if you need to cope with one of the systems failing periodically as the messaging infrastructure can hold onto the messages when the systems are unavailable. The request-response semantics can be achieved by passing a correlation id around to track conversational state. The implementation is more complicated because you don’t really want the requestor sitting blocked waiting for a response that could take an unbounded amount of time to return (eg. if the responder is busy or down).
If the complexity of a message based approach is not justified then a simple web service (that is, XML and HTTP GET requests, no SOAP or other pointless nonsense) can work very well. As an added benefit, if some thought is put into how the URLs are designed it is a relatively simple matter to insert an HTTP proxy cache (such as Squid) into the flow. Sensible use of cache directives in the HTTP headers can allow even moderately fast changing data to be cached effectively without going stale. All without having to complexify the code that returns the XML.
JDOM’s XPath implementation has (in my opinion) big glaring bug with respect to its handling of the default namespace. That’s a namespace that looks a bit like this in the XML:
<?xml version="1.0" encoding="utf-8"?>
... some stuff ...
... some foo stuff ...
Note the ‘xmlns=…’, denoting the default namespace. As opposed to ‘xmlns:foo=’ which denotes the ‘foo’ namespace.
Let’s say I wanted to run an XPath query for: ‘//myChildElement’:
XPath xPath = XPath.newInstance("//myChildElement");
List nodes = xPath.selectNodes(aDocument);
This will never work. XPath does not play nicely with default namespaces. The solution is to register the same namespace URI against a made-up prefix and change the XPath like so:
XPath xPath = XPath.newInstance("//dh:myChildElement");
The query should then work. This is not a new problem.
As a developer, of course I went off and found the webkit benchmark. Results below, in all their ugly unformatted glory:
TEST COMPARISON FROM TO DETAILS
** TOTAL **: 2.28x as fast 5387.6ms +/- 0.6% 2358.2ms +/- 0.2% significant
3d: 3.69x as fast 621.6ms +/- 1.1% 168.6ms +/- 4.0% significant
cube: 5.35x as fast 229.0ms +/- 1.3% 42.8ms +/- 11.5% significant
morph: 2.88x as fast 205.4ms +/- 1.4% 71.2ms +/- 5.7% significant
raytrace: 3.43x as fast 187.2ms +/- 2.1% 54.6ms +/- 3.1% significant
access: 6.93x as fast 885.6ms +/- 0.9% 127.8ms +/- 4.3% significant
binary-trees: 13.7x as fast 112.6ms +/- 0.6% 8.2ms +/- 12.7% significant
fannkuch: 8.92x as fast 401.2ms +/- 0.1% 45.0ms +/- 2.0% significant
nbody: 4.86x as fast 210.8ms +/- 2.7% 43.4ms +/- 10.0% significant
nsieve: 5.16x as fast 161.0ms +/- 1.7% 31.2ms +/- 4.4% significant
bitops: 8.42x as fast 796.8ms +/- 0.2% 94.6ms +/- 5.3% significant
3bit-bits-in-byte: 26.6x as fast 154.2ms +/- 0.4% 5.8ms +/- 17.9% significant
bits-in-byte: 17.8x as fast 217.2ms +/- 0.5% 12.2ms +/- 8.5% significant
bitwise-and: 5.51x as fast 178.6ms +/- 0.9% 32.4ms +/- 4.4% significant
nsieve-bits: 5.58x as fast 246.8ms +/- 0.2% 44.2ms +/- 7.0% significant
controlflow: 28.3x as fast 113.2ms +/- 0.5% 4.0ms +/- 22.0% significant
recursive: 28.3x as fast 113.2ms +/- 0.5% 4.0ms +/- 22.0% significant
crypto: 5.29x as fast 405.0ms +/- 0.3% 76.6ms +/- 4.8% significant
aes: 4.97x as fast 153.2ms +/- 0.7% 30.8ms +/- 6.0% significant
md5: 5.27x as fast 126.6ms +/- 1.1% 24.0ms +/- 8.2% significant
sha1: 5.74x as fast 125.2ms +/- 0.8% 21.8ms +/- 2.6% significant
date: 1.07x as fast 416.2ms +/- 1.1% 389.6ms +/- 1.6% significant
format-tofte: 1.23x as fast 261.4ms +/- 1.3% 212.2ms +/- 2.0% significant
format-xparb: *1.15x as slow* 154.8ms +/- 1.0% 177.4ms +/- 1.8% significant
math: 3.79x as fast 619.6ms +/- 1.1% 163.4ms +/- 5.6% significant
cordic: 3.24x as fast 294.2ms +/- 0.9% 90.8ms +/- 6.2% significant
partial-sums: 3.39x as fast 177.8ms +/- 2.9% 52.4ms +/- 11.3% significant
spectral-norm: 7.31x as fast 147.6ms +/- 0.5% 20.2ms +/- 2.8% significant
regexp: *1.88x as slow* 305.8ms +/- 10.1% 573.6ms +/- 0.5% significant
dna: *1.88x as slow* 305.8ms +/- 10.1% 573.6ms +/- 0.5% significant
string: 1.61x as fast 1223.8ms +/- 3.3% 760.0ms +/- 1.4% significant
base64: 1.81x as fast 154.8ms +/- 2.2% 85.6ms +/- 9.5% significant
fasta: 3.84x as fast 306.0ms +/- 2.1% 79.6ms +/- 2.6% significant
tagcloud: - 216.0ms +/- 3.5% 209.0ms +/- 1.5%
unpack-code: 1.36x as fast 378.0ms +/- 10.1% 278.2ms +/- 2.3% significant
validate-input: 1.57x as fast 169.0ms +/- 2.9% 107.6ms +/- 2.4% significant
That’s looking a bit more believable. On average Chrome/V8 seems to be twice as fast as Firefox/Spidermonkey, with results varying from 30 times faster to almost 2 times slower. It will be interesting to see how Tracemonkey compares, as it seems to be about 1.8 times faster than Spidermonkey.
Ruby is so, like, web 2.0. More than two graduating classes have, er, graduated since Ruby became the next big thing. That makes it nearly your grandad’s social networking application programming language, in these ‘internet speed’ times we live in. This would be the same community that has just realised that network connections that survive beyond a single request are actually quite useful. But that’s my XMPP / HTTP rant, not this one.
- Perl: Larry Wall
- Python: Guido van Rossum
- Ruby: Yukihiro Matsumoto
- Java: Sun
- .Net: Microsoft