My comments on D-BUS
David A. Wheeler
dwheeler@dwheeler.com
Thu Jan 20 18:40:47 PST 2005
Hi, I took a peek at the D-BUS Spec (version 0.8) and the
D-BUS tutorial (version 0.2) as posted on the web.
Here are some comments, which I hope you'll find useful!
(I found out that there have been some major changes in CVS
after I read the spec & tutorial; I've tried to compensate,
but my apologies if some have been overtaken by events).
In the specification:
* I didn't see any reflection capability. I think it's important
that a program be able to query for what applications and
application objects exist, what methods exist for each object,
and what parameters are required for a given method.
You can ListServices, but that's not enough.
This wouldn't be hard to do; you just need to specify
standard methods for asking for such information, if an
application object wishes to provide this information,
so that they can provide it. In the long term I think
DBUS use will be greatly simplified by an IDL processor,
and the IDL processor can generate all that automagically,
so it's no big deal to provide that.
* If you're going to make this a standard way for interoperation,
consider eventually submitting the spec to a standards body.
The IETF might be a plausible place. You'll have to be able
to justify why it's worthwhile, a point I'll get to in
a later email.
* In the glib mapping (for spec and the tutorial),
s/dbus_g_proxy_end_call()/dbus_g_proxy_make_call()/
or some other name. "ending" a call makes it sound like
you're cancelling a partly-completed call, but really,
you're finishing up the call, having it sent, and waiting
for a reply if you're waiting.
* Why is the reply optional if one isn't expected?
It seems that a reply is: (1) required or (2) shouldn't happen.
If you want a "reply optional", I'd also like to see a
"do not reply" markings... for many programs, I'd expect
that if they don't expect a reply, they don't want to have
to program in handling a "possible" reply.. they just don't want one!
And it'd be clearer if caller could clearly state
"don't send me a reply, I will NOT use it".
* Before you set this in stone, I think you NEED to figure
out how to handle sending things over a wider internet.
People don't want to have to deal with 15 different RPC
mechanisms, and I fear that it may have to have fundamental
changes to handle internet-level commo. Maybe not; the
byte-ordering marker is a clear help, for example... but
until someone's thought it through, it'll be a big question.
* There should be UTF-16 and UTF-32 value support.
A binding would probably translate UTF-8/UTF-16/UTF-32
to whatever the normal language format is, and it
takes little code to do so, but it's inefficient to
translate strings back and forth when it's unneeded.
For example, Java in particular stores strings as UTF-16;
a Java program communicating with a Java program would
find it far more useful to send the data as UTF-16;
let the receiver translate when needed.,
If efficiency didn't matter, then why send numbers as
binary values instead of as text? It's more work to
translate the strings! And although few networks care
enough for the format to matter, UTF-16 is actually
more efficient for Asian text.
* There should be a 16-bit signed and unsigned value
(this was in, and then removed in December). This is
needed to simplify the creation of bridges to other
RPC mechanisms (CORBA, for example, supports both),
and to support arrays of these values.
It's also reasonable for symmetry if you support UTF-16.
* I was going to suggest adding a STRUCT (esp. for arrays),
but it looks like that's happening already.
* Keep type 'Dict'. Dictionaries are _NOT_ the same as
'an array of (String, Value)'; arrays have an ordering,
and it's perfectly reasonable for a receiver to
expect that the ordering has meaning. Many languages (Python,
Perl, etc.) have a built-in dictionary type where the ordering
of the strings is irrelevant. Having a way to
convey 'order doesn't matter' seems useful, so that their
bindings can immediately map such information to the
built-in dictionary, without worrying about preserving
an order when it's irrelevant.
* Are strings allowed to embed a NUL byte, since their
length is encoded? Or, if you want to do that, should
you be required to send an ARRAY of BYTEs?
* In the "Valid names" section, you often say
"[A-Z][a-z][0-9]_" and so on. That's confusing; in normal
regular expressions that's a phrase with exactly 4 characters
always ending in underscore. Why not just say:
characters matching the regular expression "[A-Za-z0-9_]"?
* In the "Valid names" subsections, regular expressions
that embody all the different rules as well as the specifics
below. Regular expressions are unambiguous, shorter,
and I think many understand them better anyway.
E.g., in "interface names", say
"that apply to interface names;
such names must completely match the regular expression:
[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)+
Note that specifically:..."
* Interface names - must be 3 bytes in length, not just one,
since 'a.b' is the shortest allowed.
* In Signal emission - can you include parameters like a method call?
Why not? Many languages that originally limited exceptions to
strings (like Python) have switched to permitting more information.
* There need to be a bunch of standard signals used for errors, e.g.,
wrong type, no such method, etc. Consider including more info
to help debugging.
* In the long run, at least a 'suggested' IDL would be useful.
Is there a serious problem with using CORBA's IDL, possibly
modified, even if you don't use its generator etc.?
* If you do change the protocol so that argument signatures
are sent as a separate string (instead of in-band with data),
bump the version number from 0 to 1. Reasons:
(1) permits graceful change, but really
(2) having a non-zero value there will make it much less
likely that a non-DBUS value will be accidentally interpreted
as a DBUS value.
* If you change the protocol so that argument signatures are
sent as a separate string, you might want to change some of
the bindings to exploit that (to implement some type-checking
even when you're building the call dynamically). E.G.,
whatever_begin_call(..., typestring)
now, whenever you add a parameter, compare to see if the
value is what's expected... this even lets you auto-promote
if you want to (e.g., convert ints to the "correct" value).
There are pluses and minuses to doing this, but it might
be worth thinking about.
* You ought to at least note that for some purposes you might
want to use another RPC technology, and then bridge it to D-BUS.
There are so many others (CORBA, DCE, SOAP, ...) that should
at least be acknowledged. Ideally, you should describe HOW
at least some of their concepts match.
I have another set of comments about the relationship of
D-BUS to other RPC mechanisms, but I think I'll make a
completely different email about that.
--- David A. Wheeler
More information about the dbus
mailing list