Re: GDBusProxy missing bus signals during construction



On 23/07/15 20:50, Simon McVittie wrote:
On 23/07/15 15:01, Roger James wrote:
I am trying to implement a Zeroconf service browser using a PyGobject
Gio.DBusProxy object to talk to avahi. It all works fine but the browser
randomly misses the initial one or more ItemNew signals from the avahi
server. It sometimes even misses the AllForNow signal. Subsequent
ItemNew signals are seen OK as services come and go.
In general, you cannot rely on seeing signals "from the past". Signals
on D-Bus are not specifically for you; they are broadcasts to everyone,
and might indeed have happened already. What you're seeing is a race
condition: by the time your code receives the object path and uses it to
create a Gio.DBusProxy which subscribes to signals, you might already
have missed some signals.

The conventional pattern for D-Bus looks something like this pseudocode:

* let initialized = False

* subscribe to signals with a callback like this:

   on ItemNew signal:
       if initialized:
           print("got a new item")

* call a "state-recovery" method - perhaps it's called GetItems or
   something - to catch up on anything you missed, with a callback like
   this:

   on reply from GetItems:
       let initialized = True
       for item in reply:
           print("got a new item")

1. How can I stop this happening.
If Avahi's ServiceBrowser objects have a way to "catch up", i.e.
download the current state, then use it as described in my pseudocode.

If they don't, then Gio.DBusProxy cannot represent this API
successfully, and you will have to use lower-level functions like
GIO.DBusConnection.signal_subscribe to subscribe to the signals in
general, before you call ServiceBrowserNew; and then in the signal
callback, use the sending object path of the signals to associate them
with a particular service browser object.

2. Is avahi breaking some sort of dbus protocol or convention in sending
these signals immediately a new bus connection is made?
If there is a way to catch up, that's conventional.

If there is no way to catch up, then Avahi is being unconventional here.

3. Is the a flaw in the GDBusProxy design/documenation? (sorry guys, but
have spent a while looing at this.)
If there is no way to catch up, then you would have the same problems
with any proxy-object-oriented binding, such as the ones in dbus-python,
dbus-glib and QtDBus.

I'm only not including libdbus in that list because its only way to
subscribe to signals is analogous to the lower-level
Gio.DBusConnection.signal_subscribe API.

Hi Simon, Hi Andrejs

The "AvahiServer" object (proxy) is responding to the call to it's ServiceBrowserNew method by sending back the 'path' you should connect to and create an "AvahiServiceBrowser" proxy object on. This is immediately followed by a broadcast of the 'catch up' information. So I guess it is a problem with Avahi, because it is obvious that it is purely chance if you manage to create the "AvahiServiceBrowser" proxy in time to get the update.

I propose to get this by round this by subscribing to the Avahi ItemNew signal on my "AvahiServer" proxy to catch the updates and then unscribing it after I have connected the gobject signal on the 'AvahiServiceBrowser' proxy. Even just typing that makes ny head hurt! I have no idea how that will play in the heavily multi-threaded enviroment this is eventually to be deployed in.

I will post the new code back here for posterity later.

Roger




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]