[patch] direct service connections

Havoc Pennington hp at redhat.com
Wed Nov 3 21:19:40 PST 2004


On Sun, 2004-10-31 at 17:36 -0500, Colin Walters wrote:
> On Sun, 2004-10-31 at 17:50 -0500, Havoc Pennington wrote:
> > An issue here is that you seem to imply semantics that a service[1] will
> > expose the same objects and interfaces on all connections. But that
> > isn't how it currently works; the object tree is per-connection. So you
> > can't get separate "direct connection" and "via bus connection" to the
> > same objects.
> 
> I was only thinking of speed/security uses for this.  When would you
> actually want to expose separate object trees on different connections?

I'm not saying you would, only that the current API is a per-connection
object tree.

You might do multiple object trees e.g. for two unrelated uses of
libdbus.

My point is simply that we should be consistent; if semantically the
object tree should be bound to the connection, then the current API is
right; if semantically it isn't the current API is wrong. But the direct
connect feature presumably should be consistent.

The current API combines:
 - message queue
 - transport (e.g. socket)
 - object tree

This is all part of DBusConnection for simplicity. Going many-to-one for
message queues to transport is the multiplex idea that's been discussed.
going many-to-one for object trees to transport or queue would mean you
could share an object tree among direct and indirect connections.

As with the multiplex idea, the big issue is increased complexity. It's
tougher to get a MessageQueue + Connection + ObjectTree vs. just
Connection.

Of course we could go with a global singleton ObjectTree, and not expose
ObjectTree as a public object, but that makes me a little unhappy.

> > One way this could work internally is that when you activate a service
> > on the bus, the bus could "redirect" (like http redirect) to an address
> > for direct connection. The app would then establish a new connection to
> > that address if it doesn't already have one, and instantiate the object
> > proxy.
> 
> Hmm.  And whether or not the bus would do the redirect thing would be a
> flag in the .desktop file or something?

I think the service owner would tell the bus to redirect, or something
like that.

> > Location independence is something DCOP has lived without, though I know
> > some people have been unhappy with that - IIRC said people were even
> > doing something similar to what you are, i.e. transferring image data.
> 
> Really?  Does anyone have a reference for that?  Google didn't give me
> any pointers from a quick search.

I'm just thinking of personal conversations, I don't know of a web page.

> > Maybe a simple solution along the lines of yours would be to request a
> > direct redirect for *a specific object*, so something like:
> 
> And then the bindings level would ensure that only messages to that
> object are routed over the direct connection?

Right, the proxy for the specific object would be bound to the direct
Connection, and the proxy for other objects would not be.

>   I guess that makes sense,
> because then you don't have to take the reliability tradeoff for any
> other objects exposed by that service.

Another argument for this approach is that the bus connection is
normally global, so one guideline is that the actions of one code module
should not break other code modules.

> > Another line of thought on this issue is how to make the current D-BUS
> > address into the equivalent of an IOR (object reference). The idea being
> > that you could pass around in string form the full instructions for
> > accessing an *object* (not just a process). That would then be the
> > natural return value for the above RequestRedirect.
> 
> Hm.  And would application developers (who are using bindings) be aware
> of IORs?  I don't see, in this case, why they would need to be.  What do
> they buy us?

If you can generate an IOR and the app is indifferent to what the IOR
contains, that means you've defined an API where objects are location
independent. It's mostly just a way to think about the problem - how do
you make IORs work for both direct and via-bus connections?

The purpose of an IOR is just to be able to pass around a string that
can be used to access an object.

> > Here's another line of questioning:
> >  - say imsep starts up and owns org.fd.Imsep on the bus
> >  - you contact org.fd.Imsep and it refers you to an alternate IOR
> >  - you thus connect to the Imsep process directly
> >  - the process loses the org.fd.Imsep service on the bus
> >    and is replaced by another process owning the service
> >  - what happens to the direct connection?
> 
> Yes, I think this is a tradeoff that you get with direct connections;
> you lose the reliable service tracking and message routing that the bus
> does.  I think that it probably isn't bad to just have the direct
> connection stay around if it hasn't been closed, and an app can continue
> using it.  In the important cases such as when the remote app crashes,
> *all* connections to get closed, and so the app/libdbus can notice that
> and re-request a direct connection.

It sort of breaks the location independence of the object though, I
would think. Well, it means with a direct connection you always have the
dbus_g_proxy_new_for_service_owner() semantics, while with indirect you
have dbus_g_proxy_new_for_service(). I guess we could try to say that
you can't use direct connections unless you use new_for_service_owner()?

> > [1] note here by service you mean process/application, not what dbus
> > actually calls a service 
> 
> Hm, yes, I guess you're right.  It probably isn't useful to have two or
> more open direct connections to the same process.  But on the other
> hand, it doesn't seem common for an application to own more than one
> service; would this be a problem in practice?

I definitely expect multiple services per app for the session bus.
Very easy to imagine gnome-panel or metacity for example offering a
number of services.

In most cases where you want direct though, I'd expect you want a
separate direct connect per service, e.g. for Imsep the huge messages
would ideally not block other stuff you're doing.

> On the other other hand, an application might want to explicitly use
> separate sockets (DBusServer) for each service - this allows one to have
> distinct OS-level access controls on the particular sockets.  Not sure
> if that'd be useful in practice though.

True enough.

Mention of DBusServer raises another issue - how much code do you have
to write on the server side to make all this work?


Overall - if I had to pick something today my guess is something like:

 - add ObjectTree (think of better name for it)
   random thought: keep it internal and refer to it by Connection,
   so e.g. you can create one connection from an existing one and 
   then they share objects, or you have
   dbus_server_listen_for_direct(DBusConnection*)
   that takes a bus connection and spawns connections sharing the
   objects
 - don't add MessageQueue (keep it bound to Connection)
 - have guid for each ObjectTree and include it in the address
   from the redirect, use to verify
 - have IORs (including guid in them)
 - include dbus_g_proxy_new_direct() or something like that

I'm sure there are unforeseen complexities though.

What about the old chestnut with ORBit - which port does the Imsep
server listen on, and can remote X apps get to it through the firewall,
etc.

Havoc




More information about the dbus mailing list