Gimme, Bigboard, etc.

Alex : I just wanted to quickly respond here to the points that you raise. First, Bigboard is not some huge skunkworks project; it’s a prototype with slightly more than one person working on it for slightly more than one month, with all the source code in an open repository. And before we put any code down, we showed mockups and talked about our ideas at Fudcon.

But it’s the fact that it is a prototype — a place for us to try out our ideas, see what they look like on the screen live, and show them to others — is why even now it’s premature to worry too much about how it relates to Gimme. We didn’t feel comfortable going to you and asking you to take let us take Gimme, require users to have an account on an unstable web service, add a hard dependency on a unstable custom canvas library, and redo the user interface to use these dependencies, in the process stripping away most of the polish you’ve added to Gimme. Maybe you’d have agreed, but I wouldn’t have, if it was my project!

A common library for writing panel-like objects in Python and GTK+ would be possible, but I really don’t see a big value there. It’s not a lot of code and adding a common dependency would mostly be another hurdle to users trying Gimme or Bigboard out. The goal here isn’t to have the minimal number of lines of code, beautiful architectural diagrams, and a coherent story about how things fit together from the start. Let’s get the ideas out, see what works, what doesn’t work, and where we we want to go. The architectural diagrams can be added later.

And because Gimme and Bigboard are both written in Python and GTK+, if the consensus ends up being that Bigboard isn’t total crack, taking the good parts of Bigboard and integrating them into Gimme won’t be a big deal.

Element identity and structured data in XML

Like most people, my first experience with XML was with document formats: XHTML, SVG and so forth. So I’ve always had the idea that an XML element represents some sort of platonic ideal object: if you have an HTML anchor element or a SVG path element, it’s well defined what it means, and what the content model is. But documents aren’t the only use for XML. For mugshot, we pass lots of structured data between the server and client via XMPP, and between the server and AJAX web pages. And we often have things like:

<user userId="abcd12abcd" name="John Doe">
    <currentTrack>
        <artist>Johnny Cash</artist>
        <song>I Still Miss Someone</song>
        <playLink service="itunes" playlink="http://store.apple.com/..."/>
        <playLink service="yahoomusic" playlink="http://music.yahoo.com/..."/>
    </currentTrack>
    <favoriteTrack>
        <artist>The Beatles</artist>
        <song>Here Comes the Sun</song>
        <playLink service="itunes" playlink="http://store.apple.com/..."/>
    </favoriteTrack>
</user>

There are two weird things about the above from the “platonic ideal” perspective. First, the <currentTrack/> and <favoriteTrack/> elements don’t really have any meaning other than the relationship of their content to the parent element. They are just “attribute” that happen to have structured XML data. The second thing is that <currentTrack/> and <favoriteTrack/> have the same structure, even though the element names are different. You could try to fix up the second problem and use a common element name:

<user userId="abcd12abcd" name="John Doe">
    <currentTrack>
	<track>
	     <artist>Johnny Cash</artist>
	     <song>I Still Miss Someone</song>
             <playLink service="itunes" playlink="http://store.apple.com/..."/>
        </track>
    </currentTrack>
    [...]
</user>

Or you could even try to fix both problems by using a generic element to represent a “XML-valued” attribute:

<user userId="abcd12abcd" name="John Doe">
    <attr name="currentTrack">
	<track>
	     <artist>Johnny Cash</artist>
	     <song>I Still Miss Someone</song>
             <playLink service="itunes" playlink="http://store.apple.com/..."/>
        </track>
    </attr>
    [...]
</user>

Or we could split things up and actually use an attribute:

<track id="track1">
     <artist>Johnny Cash</artist>
     <song>I Still Miss Someone</song>
     <playLink service="itunes" playlink="http://store.apple.com/..."/>
</track>
<user userId="abcd12abcd" name="John Doe" currentTrack="track1"/>

But I think all of those are essentially silly. The natural way to do structured data in XML is just different than a document use. When you have structured data: 1) some elements only have a local meaning in the context of their parent element. 2) there is a concept of “type” which is distinct from element identity.

Now, if there are any XML experts in the readership, they probably are now thinking that the above is some combination of blindingly obvious, woefully simplified, and hopelessly misguided. And they are doubtless right. But I found it a useful clarification of my thinking around XML design.

Just like Riding a Bike

I’ve been putting the old saying “It’s just like riding a bike, you never forget” to the test this weekend, having avoided that particular activity for the last 20 years. I’m considering buying a bike and doing some riding as a more air-cooled form of summer exercise, so I rented one this weekend to regain some basic ability. So far the results have been mixed as to whether it’s possible to forget how to ride a bike: it only took me 45 minutes riding in circles around a parking lot to regain some ability to balance, turn, and stop, but the ground sure does seem further away than when I was twelve. Goal for tomorrow morning: relax my death grip on the handlebars and hopefully end up not feeling like I’ve been bench-pressing weights all day, as I do right now.

Update: moderate success. I certainly feel less trashed this evening than I did yesterday, after riding for somewhat longer today. I even saw one person on the trail that I was probably more skilled than. Of course, he was about 7 and using training wheels.

There are no harmless race conditions

I spent most of Friday tracking down a problem we had been seeing with the Mugshot Windows client for months, where important parts of the client (Mugshot.exe) would mysteriously vanish from the system. This happened to both Bryan and Havoc when we pushed a new client release last week. Using information from that, combined with uninstalling and installing things about 200 times, I was able to track the problem down to the following sequence:

  1. When the upgrade starts, we tell the old client to exit
  2. The Windows Installer goes to remove the old version, and finds that Mugshot.exe is still in use, so it schedules a delete after the next reboot
  3. The old client actually finishes exiting.
  4. The Windows Installer installs the new files, and since Mugshot.exe is no longer in use, immediately replaces it with the new version, instead of scheduling that action to happen after reboot.
  5. The user is prompted to reboot the system, and after reboot, Mugshot.exe is deleted.

The fix, once tracked down, was pretty simple … just actually wait for the old client to finish exiting before proceeding. Now, I knew when I originally wrote the code the race condition could happen, but convinced myself that It Will Be Very Rare: the Windows installer has all sorts of other work to do as well, and the client will exit quickly. And also It Will Be Harmless: maybe the user will be told to reboot unnecessarily, but that’s all. As is almost always the case, neither was in fact true.

Other thing I should have known better about this weekend: when attending an outdoor music festival in the rain, waterproof footware will make the experience vastly more enjoyable, even if the music is worth it.

Do they have sheep in Burma?

Warning: the following is not for those overly squeamish about dietary fat, nor for the ethnic cuisine purist.

I made the following stew on Sunday and have been feasting on the leftovers for the last two nights. It has no actual connection to Burma (or Myanmar), other than the combination of South and Southeast Asian flavors which I believe to be characteristic of the country. The inspiration here, other than the ingredients at hand, is the memory of the stews that one of the other students in my dorm at the University of Chicago would cook in the kitchen there. I don’t know what part of Southeast Asia she was from — almost certainly not Burma — and I never got up the courage to ask to try one of the stews, but they always looked mysterious and smelled great.

The recipe should work as well with beef or even, I’d guess, goat. You don’t want a fine cut of meat for this: in the long cooking, the fat and connective cookie dissolve and combine with the coconut milk into an luxurious, even unctuous broth.

I served this over a Japanese medium-grain rice, but a Southeast-Asian sticky rice, or even arborio would work as well. In fact, the combination of the creamy broth with moist and slightly chewy rice is reminiscent of risotto. I would avoid Basmati or Jasmine rice … the broth should coat the rice, not be absorbed by it.

 "Burmese" Lamb Stew

  1.5lbs bone-in lamb stew, cut in 2 inch chunks

  1/3 cup canned coconut milk
    1 tbsp fish sauce
    1 small onion finely diced
    2 medium potatoes, peeled and cut into 1 inch chunks
    2 tsp fresh marjoram, finely chopped

    2 tsp fresh ginger, cut into fine shreds
    1 tsp ground coriander
  1/2 tsp turmeric
  1/4 tsp cayenne pepper
    4 whole green cardamon pods
    2 bay leafs
    8 black peppercorns

      Peanut oil

 Brown the lamb on all sides in oil over medium-low heat in a
 dutch oven or similar. Use multiple batches if necessary to
 avoid overcrowding the pan. Remove lamb from pan and drain on
 paper towels.

 Refresh oil if needed, add onion, and cook over low heat until
 the onion is soft and beginning to brown. Add ginger, whole and ground
 dried spices and saute briefly until the spices are fragrant.
 Add lamb and 3-4 cups water (enough to just cover the lamb), bring
 to a boil, reduce heat, and simmer partially covered for 2 hours.

 Add potatoes and fish sauce, cook for 20 more minutes until the
 potatoes are cooked, add coconut milk, return to a simmer, taste
 and add salt if the dish is insufficiently salty from the
 fish sauce.

 Serve over medium grain rice with a side salad of yogurt, cucumbers,
 and finely chopped red onion. Makes 3 small but rib-sticking
 portions.

Notes: All quantities above are approximate and from memory. The lamb should be completely tender and coming off the bone, but the potatoes should keep their shape. Don’t eat the cardamon pods, bay leaves, or peppercorns.