I made a thing

A while ago I made a prototype of a simple, high-performance keyword search for bugzilla, using python and Redis.  It was pretty promising, able to do all/any queries against the summaries of all open Firefox bugs in a handful of milliseconds.  The bugzilla maintainers decided to use the database’s full-text engine instead, but I was nonetheless pretty pleased with it.

A month or two ago, I started rewriting it it atop node.js and gave it a simple websocket-based interface.  (It took a while, due to The Unpleasantness rather than the difficulty of the task itself.) It was blazingly fast, easily able to keep up with real-time matching of entered keywords. The queries on the server side were finished in a dozen milliseconds or less, and the remainder of my 200 millisecond request budget was spent on data transfer back to the client. I had to limit the returned result set to the most recent 100 items to keep the transfer time down. I will probably look at compression in JS to improve things there. (Some requests take as much as half a second if I get unlucky on the network and result-set size.)

Building the index takes about 20 seconds on its wimpy VM, though retrieving all the summaries from bugzilla takes a fair bit longer. (It currently indexes open bugs in Firefox, Fennec, Core, Toolkit, NSPR and NSS.) I could do that on a timer and have it be current within 10 minutes, but it would be pretty wasteful: the rate of relevant change is on the order of a few dozen each minute, and updating that many summaries is literally microseconds.

Enter Pulse, Christian Legnitto’s mozilla-wide message broker.  Wired up to Pulse, my index is up to date cheaply every 5 minutes, and once we deploy the bugzilla extension, the index will be updated within fractions of a second.

To support non-websocket browsers, which is currently all of them, I switched to using socket.io for the transport.  The flashsocket transport adds about 100 milliseconds to the round-trip, which is unfortunate but here we are.

In all, it’s about 500 lines of JS on the server side, plus another ~150 lines for the scripts that do the loading, and I think it’s a great example of what tools like pulse and the Bugzilla REST API are going to make possible in 2011. It’s also an example of how holy-crikey excellent Node and Redis are together.

(There’s an installation running here, which might randomly break as I hack on it.)

Update, 2 minutes after posting:

23 Jan 00:16:00 - searching for sex 23 Jan 00:16:00 - undefined: search 1 -> 1 in 0/1 ms
Hi, Internet.

another random bit of instrumentation

Last week, I was wondering about how the frame freelist/recycling/arena behaviour might impact dynamic memory footprint, especially for long-lived pages that do a lot of DOM-whacking. So in a few hours on Friday and today I whipped up an ugly, ugly patch that tracks the total outstanding “live” frame size for a given PresShell instance, and the total size of those that are being kept on the freelist. I doubt I’ll have much time to do more with it, but it might be an interesting addition to about:memory when that gets rolling. I’d also like to make the frame counting not be debug-only, and surface that information as well, just for kicks.

[ { uri: "resource://gre/res/hiddenWindow.html", allocated: 11768, onFreelist: 212 },
{ uri: "chrome://browser/content/browser.xul", allocated: 172775, onFreelist: 15064 },
{ uri: "http://www.mozilla.org/projects/minefield/", allocated: 88944, onFreelist: 1292 },
{ uri: "http://news.google.com/", allocated: 476528, onFreelist: 2368 },
{ uri: "http://dojotoolkit.org/demos/fisheye-demo", allocated: 102379, onFreelist: 39540 },
{ uri: "http://jquery.com/plugins/project/Plugins/category/48", allocated: 166888, onFreelist: 1320 },
{ uri: "http://jquery.com/plugins/project/LavaLamp", allocated: 91904, onFreelist: 1540 },
{ uri: "chrome://global/content/console.xul", allocated: 47232, onFreelist: 313408 },
{ uri: "about:blank", allocated: 11768, onFreelist: 212 },
{ uri: "about:presshell-stats", allocated: 13620, onFreelist: 212 },