Service discovery on message bus

Simon McVittie smcv at collabora.com
Fri Mar 23 19:00:39 UTC 2018


On Fri, 23 Mar 2018 at 16:43:50 +0100, Umut Tezduyar Lindskog wrote:
> On Fri, Mar 23, 2018 at 3:18 PM, Simon McVittie <smcv at collabora.com> wrote:
> > For a more complex real-world example, see Telepathy or MPRIS2, both
> > of which define a protocol in which a family of well-known bus names
> > can be relied on to implement particular interfaces at particular
> > object paths.
> 
> These are making the assumption that Service A always know that it is
> talking to Service B that it can read Service B's documentation.

Think protocol B, not service B. Service A doesn't have to know that it
is talking to a particular *implementation*. It *does* have to know that
it is talking to an implementation of a particular protocol, otherwise
it can't know how to interact with that protocol.

For instance, if you have services that can be asked to back up their
data, then they (must) all implement the "can be backed up" protocol.
What's in that protocol is up to you, but it's that protocol that is
the interesting one for a backup service. The rest of what those
services do is not directly relevant.

> I was more thinking that services would export their objects and
> interfaces those objects are implementing in a .service dbus file.
> Attention has to be paid here to make sure objects exported are
> supporting dbus activation. In other words, by the time well known
> name is acquired, dbus objects given in .service file has been
> registered.

If your services export a static set of objects and interfaces that
can be known at compile-time or at install-time, you're more than
welcome to implement file-based capability discovery that bypasses
D-Bus altogether. Telepathy's .manager files[1] and .client files[2]
are examples of this. I think a complete list of objects is probably
excessive, but if you want to do that for your services, go ahead;
it's your maintenance burden, not mine :-)

However, the more general case on D-Bus (for which ObjectManager was
designed) is that object registrations are dynamic, and cannot be known
in advance.

If you only need static discovery that can be done with some sort
of on-disk list of "things", then going via D-Bus is just overhead.
Just because you use D-Bus for some things doesn't mean you need to use
D-Bus for everything. In principle, desktop environments could look for
apps to list in menus by asking some D-Bus service - but they don't need
that, so they look in /usr/share/applications directly. Similarly, if
looking in /usr/share/axis/backupable.d is sufficient to discover what
can be backed up, there's no shame in using that file-based interface
and ignoring D-Bus completely for that particular function.

(This is a running theme in my messages to this mailing list: I don't
want people to use D-Bus if it isn't an appropriate tool for the job.
A framework that tries to be suitable for everything ends up being either
bad at everything and good at nothing, or a massive maintenance burden.)

[1] https://telepathy.freedesktop.org/spec/Connection_Manager.html#description
[2] https://telepathy.freedesktop.org/spec/Client.html#description

> We have 2 use cases. First, we do backup/restore in our products.
> During backup time, we discover which objects at which services
> implement com.axis.backup interface and restore is the other way
> around.

If you only need static discovery of something that can be known at
compile-time or at install-time, see above.

If you need dynamic discovery at runtime, I suggest making use of the fact
that each connection (or "service", if you like) can have any number of
well-known names. In addition to the well-known name(s) used to implement
its normal functionality, you could make each service request a well-known
name of the form com.axis.Backupable.UNIQUEID where UNIQUEID is unique.

The backup service can look for names of that form, and for each one,
it can do whatever your API design says it should - perhaps contacting
a well-known "entry point" (maybe /com/axis/Backupable/UNIQUEID
with any dots in UNIQUEID replaced by slashes) and asking it to back
up its data to a specified location.

Telepathy uses this pattern in several places, and MPRIS2 uses it for
each media player. A typical media player will have several well-known
names, and that's fine: for example, GNOME's Rhythmbox media player is
probably simultaneously org.mpris.MediaPlayer2.rhythmbox (for MPRIS2),
org.gnome.Rhythmbox (for GApplication), and possibly some other well-known
name for its interactions with Rygel for UPnP. They're all aliases
for the same unique bus name representing the connection. Similarly,
a typical Telepathy client or connection manager will have lots of
well-known names, all of which are aliases for the same unique bus name.

> Second one is we extend our firmware functionality by
> installing applications. Applications declare which interface they are
> needing from the firmware. Installer looks up if there is/are objects
> implementing the given interface before accepting installation
> request.

Similarly, if you need dynamic discovery, well-known bus names
are an appropriate tool for this sort of high-level capability
discovery. Well-known bus names represent functionality supported by a
connection/service; interface names represent finer-grained functionality
supported by individual objects.

    smcv


More information about the dbus mailing list