Recently I have been working on two things related to achieving a client-server separation in Getting Things GNOME!
One is a test suite that will cover all aspects and functionality of the DBus interfaces. The second is low-level code to support the interfaces themselves.
Why not do them in sequence? Well, tinkering with the low level code is helping to outline what will and will not be possible with the "DBus magic" I've blogged about on two previous occasions. Tests don't have to target against code that already exists, but they should at least target code that could exist.
To explain more, the concept is to have more than just a DBus interface on the server. For the client, the dbus-python
Interface classes are a useful starting point, but I want to go further and let GTG! clients behave as if the objects they are handling were local (although, as James pointed out, clients will be faster if they don't naïvely trigger too many calls on the bus). This means providing a client library that clients can optionally import and use, instead of grappling directly with the server's DBus interface.
In coding this client library several interesting winkles have come up. For example, the DBus tutorial discusses the distinction between well-known names ('org.gnome.GTG') and unique names (:34-907)—but these are only for buses. Each object (e.g. a GTG! Tag or Task) available on a bus needs to have an object path ('/org/gnome/GTG/Task/12345' or '/org/gnome/GTG/Task/54321').
Because of the DBus message-passing architecture, there is no way to know if anything exists at a given object path, until you try to access it. By analogy, the Internet's Domain Name System (DNS) can tell you that my website
paul.kishimoto.name exists at such-and-such an IP. But to determine if there is anything at a specific URL (http://paul.kishimoto.name/notapage), you need to try to access it and maybe get an HTTP 404 error.
Clients only care about actual Tasks and Tags, and repeatedly checking that its proxies still reference valid targets would be a pain in the neck. The solution is to provide helper code that checks the remote object exists before it hands a proxy to the client.
Another problem that is cropping up is that the client needs to be able to understand and manipulate the tree hierarchy of Tags and Tasks, over the bus. But that will be another post…