Monitoring lifetimes with Python bindings
John (J5) Palmieri
johnp at redhat.com
Fri Jul 8 04:59:47 EST 2005
On Thu, 2005-07-07 at 15:02 +0200, Ole Laursen wrote:
> Havoc Pennington <hp at redhat.com> writes:
>
> > On Wed, 2005-07-06 at 16:45 -0400, John (J5) Palmieri wrote:
> >> @dbus.explicitly_pass_message is mainly for debugging. Messages should
> >> not be exposed in the python bindings. The best thing to do is for your
> >> client to send its unique name to the server when it connects to the bus
> >> and register the NameOwnerChanged signal with sender equal to the name
> >> you received. You can also use the GetNameOwner call to get the unique
> >> name of an already running process.
> >
> > I think exposing messages would be wrong but exposing the caller of a
> > method may not be if we could figure out a good approach.
>
> Perhaps one possibility would be to use another decorator, e.g.
> @dbus.pass_sender, which would pass a Sender object. Sender could then
> expose get_name() to return the unique name and a disappeared() hook
> that you can connect to. The disappeared() hook would then internally
> register with the NameOwnerChanged signal and also call GetNameOwner
> to avoid the race condition.
>
> Does this sound like a good idea?
While we may need to expose things like sender I am hesitant to do so
for this example. I would however not be opposed to creating an API for
keeping track of name owner changes, disconnections and reconnection's.
So say something like:
bus.watch_for_disconnect("org.foo.Bar", on_disconnect)
bus.watch_for_name_owner_change("org.for.Bar", on_name_owner_change)
These assume that org.foo.Bar is already attached to the bus because
there is no way to know when it appears on the bus. It would be nice to
add a signal to the spec that broadcasts when names are added to the bus
so we can listen for them and register when they do. The I could have
API like bus.watch_for_connect("org.foo.Bar", on_connect).
Anyway, for your problem right now you might want your server to have an
API where clients can register themselves so you don't have to worry
about the sender object:
@dbus.method("org.foo.RegistrationInterface")
def register_object(self, sender_unique_name):
Then your clients can get a name on the bus, ask the bus for it's unique
name and then register with the server.
I need to sit down and think things through before I start adding new
API.
> Perhaps something like the following snippet (I'm not a Python
> expert, but it appears to work):
>
> class Sender:
> def __init__(self, unique_name, bus):
> self.unique_name = unique_name
> self.bus = bus
>
> def get_name(self):
> """Return the unique name of the sender."""
> return self.unique_name
>
> def register_disappeared_handler(self, disappear_handler, error_handler):
> """Register a handler which is called when sender disappears."""
> self.disappear_handler = disappear_handler
> self.error_handler = error_handler
> self.disappear_handler_called = False
>
> bus_obj = self.bus.get_object("org.freedesktop.DBus",
> "/org/freedesktop/DBus")
> bus_obj.connect_to_signal("NameOwnerChanged",
> self._name_owner_changed_handler,
> dbus_interface="org.freedesktop.DBus")
> bus_obj.NameHasOwner(self.unique_name,
> reply_handler = self._name_has_owner_reply,
> error_handler = error_handler,
> dbus_interface = "org.freedesktop.DBus")
>
> def _name_owner_changed_handler(self, name, old_name, new_name):
> if old_name == self.unique_name and new_name == "":
> if not self.disappear_handler_called:
> self.disappear_handler_called = True
> self.disappear_handler()
>
> def _name_has_owner_reply(self, has_name):
> if not has_name:
> if not self.disappear_handler_called:
> self.disappear_handler_called = True
> self.disappear_handler()
>
> --
> Ole Laursen
> http://www.cs.aau.dk/~olau/
--
John (J5) Palmieri <johnp at redhat.com>
More information about the dbus
mailing list