Great Minds Think Alike: Asynchronous Patterns

March 29th, 2010 by John Carr

Isn’t writing synchronous code nice?

function do_stuff () {
  do_thing_one ();
  do_thing_two ();
  do_thing_three ();
}

But synchronous is bad! Bad, bad, bad. So then came async. The simple pattern is to pass a callback to the function you are calling. It’s not as bad in JS because we just can do this:

function do_stuff () {
  do_thing_one ( function (result) {
    do_thing_two ( function (result) {
      do_thing_three ( function (result) {
      });
    });
  });
}

I’ve left out error handling. That really depends on the library.. But i imagine its messy. Now let’s see GIO style async.

function do_stuff () {
  do_thing_one_async ( function (ar) {
    var result = do_thing_one_finish (ar);
    do_thing_two_async ( function (ar) {
      var result = do_thing_two_finish (ar);
      do_thing_three_async (function (ar) {
        var result = do_thing_three_finish (ar);
      });
    });
  });
}

I like this a lot better than how i’d do it in python. But wouldn’t it be nice if you could write async code something like this?

var do_stuff = async (function () {
  var result = yield do_thing_one ();
  yield do_thing_two ();
  yield do_thing_three ();
});

Or even:

var do_stuff = async (function () {
  var result = yield do_thing_one ();
  yield do_thing_two ();
  try{
    yield do_thing_three ();
  } catch (e) {
    print("Exception handled");
  }
});

You can in python. You can in vala.¬†And for JS? Well, I was going to say “now you can“. But while I was looking for a good Vala link, I noticed Alex already did something like this over a year ago. D’oh.

What would be really nice is if the async wrappers could be generated automatically by GI. I had a first stab at this by simply parsing the GIR xml with E4X and providing an alternative import mechanism (thanks for the suggestion jdahlin). However to get full coverage i’d have to consider interfaces and inspect every object that implements an interface as it lands in JavaScript land to ensure it is wrapped. Ew.

Sysadmin Team Meeting, Bugzilla

August 11th, 2009 by John Carr

Despite the constant threat of bike shedding, the sysadmin team will be hosting a small irc meeting (on #sysadmin) in the near future. Feel free to join in and tell us how much you love us <3. See here for more details, and here to help us choose between Friday and Sunday.

Minutes from the last meeting are here.

On a related note, one of the tasks to come out of the last meeting was to try and make bugzilla faster, or at least come up with a plan. That task kind of disappeared, because the bugzilla 3 porting work is now finished. Yes, as you may have seen, Bugzilla 3 is coming!!.

I’m not afraid of people using JHBuild

July 15th, 2009 by John Carr

Just a quick blog to point you at the external dependencies branch of JHBuild i’ve been working on.

The external deps branch aims to do 2 things:

  • Don’t jhbuild any modules that are already system installed
  • Add a new command to jhbuild to install system packages so they don’t need to be jhbuilded

It pretty much works, it needs massaging into shape to merge into master. Then we need to collect some meta-data:

  • Minimum versions. How do we know if the system installed glib is new enough? I added a minimum=”" annotation to the dependency information we already have.
  • Package names. Right now it’s a bit difficult to map jhbuild module names to package names. I’ve added aliases files for now, and some crude python to try and infer the aliases for Debian. Better ideas welcome.

I also need to get round to a PackageKit backend so it supports more than Debian/Ubuntu :]

If you want a jhbuild where ‘jhbuild build gedit’ only builds the least amount of stuff, help me :]

July 10th, 2009 by John Carr

i am not afraid of people writing code

The best of Channel 4, on demand

May 16th, 2009 by John Carr

Noticed that Channel 4′s on demand service 4oD is now advertising mac compatibility. So I gave it a shot on Ubuntu Jaunty (with the full fat dirty evil flash 10). Ladies and gents, it looks like 4 on demand now works on Linux too, shame they didnt advertise that on the tele.

Playing with RDF

May 15th, 2009 by John Carr

I’ve been playing with the master branch of tracker and i’m loving it – it looks like its finally reached the stage where I won’t just turn it straight off after a fresh install.

It now brings GNOME an RDF store with a SPARQL interface. Powerful joo-joo, but kinda scary if you haven’t seen it before. Most conversations about it lead to words like graphs, triples, ontologies… My eyes start to gloss over.. I need to learn by doing. So i’ve been playing with writing some python wrappers to hide tracker and just provide a familiar pythonic interface.

Any object type that tracker knows about will be available in python via the wonders of introspection. All properties of the class are available, with docstrings explaining the intent of the property and its type. Obviously you can get, set and delete and do simple queries. And behind the scenes are SPARQL queries in all their glory. Theres a lot still to do, but enough done that I can synchronise my address book to Tracker with Conduit (see my tracker branch).

So far it looks something like this (but its subject to very rapid change):

import tralchemy
from tralchemy.nco import Contact

# add a contact
c = Contact.create()
c.fullname = "John Carr"
c.firstname = "John"
c.nickname = "Jc2k"
c.commit()

# find all the people called John
for c in Contact.get(firstname="John"):
  print c.uri, c.fullname

# subscribe to any contact changes
def callback(subjects):
  print subjects
Contact.notifications.connect("SubjectsAdded", callback)

# Will probably be just:
Contact.added.connect(callback)

While get() is a nice way to do simple queries, what if you wanted to do something a little more complicated. It always feels messy when you have SQL or SPARQL nested in other code. Existing SQL ORM tools are a great place to start at avoiding this, but i quite like the LINQ style generator-to-SPARQL. Something like:


q = Query(Contact.firstname for Contact in Store if Contact.nickname == 'Jc2k')

or


q = Query(c.firstname for c in Store if c is Contact and c.nickname == 'Jc2k')

Hmm decisions. Hope to implement similar abstractions in JavaScript, C# (via LINQ) and Vala (via Magic). Anyone wanna share their cloning tech?

Mercurial and Git

May 3rd, 2009 by John Carr

Jelmer just pinged me to show me a new fangled Mercurial plugin. Thats right folks – pulling and pushing between Git and Mercurial! It uses the dulwich library that I worked on with Jelmer (was the basis for my “git serve” crack and is also used for pushing and pulling between Bazaar branches and Git with bzr-git).

Coolness.

I look forward to seeing some new dulwich patches (they are using a patched copy right now).

On git.gnome.org and GitHub

April 27th, 2009 by John Carr

When GNOME SVN was migrated to Git all your commits were attached to a generated e-mail address in the form username@src.gnome.org.

If you have a GitHub account you can go to your settings and add that e-mail address. Now all the old commits you made will be associated with your account when viewed on GitHub. If you’re a fan of the cute GitHub graphs, you’ll love this too.

Sysadmin Team

April 17th, 2009 by John Carr

Owen just announced the formation of formal sysadmin team which I will be coordinating on an interim basis.

Want to join the team? Want to get your pet peeve fixed? Everything will unfold on the gnome-infrastructure mailing list, so sign up there if you want to get involved!

Calling All Git Beginners

April 15th, 2009 by John Carr

Tomorrow we move to Git! If I could offer you one piece of advice, git config would be it. Just a simple:

git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com

on every new machine you use Git on. Otherwise the history is going to look like crap (look at the email address).

commit 9dea54aab2c97181f8d8c67a8cdce956baa30d05
Author: Gnome User <gnome@ubuntu-desktop.(none)>
Date:   Tue Apr 7 10:17:13 2009 +1200

That is all.