GBus discussion

Havoc Pennington hp at redhat.com
Sat Aug 18 21:51:21 PDT 2007


Hi,

Well, this is a very small detail so I would suggest if you're
planning to work on some proposed code and try it out in some apps,
you continue without waiting to decide this for sure ;-)

But I will keep talking just in case it's helpful -

On 8/18/07, Fan Wu <wufan9418 at gmail.com> wrote:
> So I'd still prefer just passing the all the info directly to
> callback, if just to save people coming back and asking for it.
>

Remember, this is a convenience API intended to save people time and
save them from learning about all the low-level details.

The question here is: can you document the errors that might be passed
in, and how the application should handle them?

If there are no errors a reasonable application should handle (and I
believe there are not), then providing an error is making people type
stuff and learn more ("do I have to handle this? let's read the
docs...") for no reason. It's actively harmful to provide an error
object that can never have anything interesting in it.

There is no question of "future-safeness" because it would not be
backwared compatible to add errors that a reasonable app should
handle.

If you really wanted to be paranoid, you could pass some type of
"context" object to all callbacks, which would be an opaque object
with methods like context_get_current_error() and
context_get_current_message(), or something... but I would suggest not
adding this unless it proves necessary.

I'd start by writing a simple API, then try it out in a few real-world
apps, and then add complexity only as truly proven necessary.

Remember, people can always use the low-level API if they want to do
something unusual. If you make the high-level API totally flexible, it
will be just as ugly as the low-level API. Flexibility is why the
low-level API is so ugly.

A high-level API should be about doing some of the complex stuff for
you and hiding details, and I think "hypothetically, if there were a
bug in the message bus or the machine were so hosed a trivial
operation took 5 minutes, an error could be returned here" is
certainly a detail we could hide.

Regarding specific concerns,

 - I don't think the app should care why it lost the name, but if it
really did then checking dbus_connection_get_is_connected() should
reveal whether it was due to disconnection or replacement

 - the error handler always has to be called in the dispatch thread,
so you should only get re-ordering if you can also get re-ordering of
messages (i.e. if you don't have a defined dispatch thread). In any
case, since this handler is really only for debug logging I doubt it
matters. (fwiw, I'm not sure the error handler function is even
necessary; debug logging can also be accomplished by installing a
message filter; all the handler really adds is a distinction between
"all errors" and "unexpected errors" which might allow you to leave
the unexpected-error logging enabled in production code, while you
could not leave all-errors logging enabled)

If there were truly errors an app needed to handle, I think it would
be better to convert them into higher-level concepts, for example by
having a separate "disconnected" callback, or an enum like:

 typedef enum {
   GBUS_LOST_NAME_REPLACED,
   GBUS_LOST_NAME_DISCONNECTED
 } GBusLostNameReason

Then it would be clear from looking at the API what an app needed to
handle, while a DBusError is very vague.

However, I think in this case there probably are not any errors or
separate cases most apps have a reason to care about. At least I can't
think of any.

I think it's ideal if the app doesn't care about the connected state
at all. When disconnection occurs, the default would be to exit.
However, if dbus_connection_set_exit_on_disconnect() has been called
to disable exit, I would suggest that the high-level API keeps trying
to reconnect (perhaps every 30 seconds or something). A
properly-written app will do exactly the same stuff on reconnect that
it did when it initially connected.

In that case, most of the time apps would not need to care about the
connected state - they would just need to care about getting their
single instance bus name (in which case they initialize the app and
start doing stuff) or losing their bus name (in which case they either
exit, or they un-initialize and wait to get the bus name back).

Havoc


More information about the dbus mailing list