The Advisory Boar

By Abhijit Menon-Sen <>

Avoiding asynchronous callback hell in Archiveopteryx

I've read many mentions of “callback hell” recently, especially in discussions about Javascript programming. This is the problem of deeply nested code when trying to manage a sequence of asynchronous actions. The many suggested remedies range from splitting the code up into many small named functions to async to promises to futures (and probably other things besides; I haven't tried to keep up).

FutureJS, for example, is described as helping to tame your wild, async code.

I have no opinion about any of these solutions. I don't work with any complex Javascript codebases, and asynchronous actions in my Mojolicious applications have been easy to isolate so far. But I do have opinions about writing asynchronous code, and this post is about why I'm not used to treating it as though it needed “taming”.

Read more…

Git: post-receive hook for XMPP notifications

Here's how I set up XMPP-based notifications for new commits to the Archiveopteryx Git repository.

Read more…

Managing release branches: git merge vs. p4 integrate

Git prefers to merge topic branches forwards, where Perforce integrates changes into back branches. Life becomes easier if you can work with each program's preferred model.

Read more…

#ifdef considered harmful

Speaking of portability, here's a link to Henry Spencer and Geoff Collyer's classic 1992 USENIX paper #ifdef Considered Harmful, or Portability Experience With C News.

We believe that a C programmer's impulse to use #ifdef in an attempt at portability is usually a mistake. Portability is generally the result of advance planning rather than trench warfare involving #ifdef.

It's been eighteen years since its publication, but not enough people have read that paper yet.

Mirroring a git repository

Here's how I set up a post-receive hook to maintain multiple mirrors of the main Archiveopteryx git repository.

Read more…

Portability and optimism

We've always taken a very conservative approach to portability with Archiveopteryx. We run it ourselves under Linux and FreeBSD on x86 and x86_64 systems, and those are the only platforms we've ever claimed to support. Between the developers and our major users, we have access to enough systems of that description that we can be reasonably confident that the software will work without unpleasant surprises.

Beyond that, we've never been very ambitious. Once in a while, someone would ask Does it work on NetBSD? or Solaris or OS X. The answer was usually yes, perhaps after a few (relatively minor) tweaks. We would add #ifdefs and other portability patches to our code only after someone suffered from an actual problem, never before. If we couldn't (or didn't, regularly) test it, it wasn't supported.

This gloomy approach is in sharp contrast to the confidence encouraged by autoconf. Had we used it, we could have saved a few users the trouble of dealing with compile errors. We would have been testing our software only on the few systems we did anyway (which happen to be the commonest platforms in use), but autoconf would have helped us to feel more portable. I don't want to think about what that would have done to the number of unreproducable bugs we had to analyse; they were enough trouble as it was.

I was recently reminded of our curmudgeonly attitude in a conversation with Hassath, who did a project on FLOSS video editing software. One of her complaints was that it was hard to find out not just what the hardware and software dependencies of some program were, but also what configurations were known to work. The documentation usually implied that any Linux system would work fine, but in practice, people running a different distribution routinely encountered problems that the developers had never seen and had no idea how to address. This was the case even on her quite unremarkable Ubuntu and amd64 test system, and she found it extremely frustrating.

Try as I might, I can't see optimism as a good approach to portability.