Am Donnerstag, den 27.05.2010, 11:39 +0300 schrieb Jussi Kukkonen:
On 05/27/2010 12:38 AM, Frederik Elwert wrote:
> Thank you very much for the reply!
>
>>> So what would be the best way to get a sync report from a
>>> session that I did not create by myself? Is there a way to
>>> "attach" to a third-party session in order to prevent it
from
>>> being destroyed?
>>
>> I wonder if you need to? Could you just do a Server.GetReports() -- I'm
>> pretty sure that's what I do.
>
> Server.GetReports requires a 'server' parameter. But how do I know for
> which server the specific session has been requested? So if I get a
> Session.StatusChanged signal and want to pull the sync reports, I cannot
> tell against which server this session synced. I feel like I overlooked
> something, but did not find out how to solve this.
Hmm, I see the problem. I have not stumbled on it as I only show reports
for syncs I initiate, and have the server name in store already...
If it's enough to get the last sync report (regardless of server), you
can do:
GetReports ("", 0, 1)
I now notice this is not documented (filed bug 2471): Empty server name
will give you reports for all servers.
The problem you mentioned is real: Being able to find out the server
name from session might be useful, but maybe the above will be a a good
solution for your specific situation?
Yes, this really helps. Thanks!
>>> 2. Getting information about the purpose of a session
>>>
>>> When I want to sync, I create a session. Because I have to wait
>>> for the session to become ready, I connect to the
>>> `SessionChanged` signal. But of course, I get a `SessionChanged`
>>> for all sessions, not just the one I just requested for syncing.
>>> So how do I know that the session I am getting notified about is
>>> the one I requested for the sync?
>>
>> [clip]
>>
>>> So to make a long story short: How would I properly know if a
>>> session I get the `SessionChanged` signal for is requested by me
>>> in order to perform a sync?
>>> (I tried to understand what sync-ui does, but miserably failed
>>> reading the source code. That is way too deep for me.)
>>
>> That part is a bit complex because of the same problems you are solving
>> :) The short answer is that you probably don't need that knowledge in
>> SessionChanged.
>>
>>
>> sync-ui does follow Server.SessionChanged and even subscribes to
>> StatusChanged of the sessions (regardless of who started them): this is
>> necessary if we want to to show all syncs in the UI somehow. But the
>> solution to your problem is to subscribe to Session.StatusChanged in the
>> function that handles Server.StartSession() return value.
>>
>> So, sync-ui has two different Session.StatusChanged handlers: one for
>> all sessions (this will e.g. update the progress bar and set the UI
>> sensitive/insensitive) and another one for just Sessions started by
>> sync-ui (this is the one that is subscribed to in StartSession() handler
>> and will e.g. start a sync when status becomes idle and gets the reports
>> afterwards).
>
> This sounds totally reasonable, and I expected it to work smoothly, but
> it seems I am running into another race condition. I have the following
> handler for sync:
>
> def sync(self, widget, server):
> session_path = self._syncevo_server.StartSession(server)
> session = get_session_interface(session_path)
> session.connect_to_signal('StatusChanged',
> self._status_changed_callback_sync,
> path_keyword='session_path')
> print session.GetStatus()
>
> Now I wait for the 'idle' status in _status_changed_callback_sync and
> will call session.Sync('', {}) there.
>
> But I never get a Session.StatusChanged signal. As the output of
> session.GetStatus() shows, the session is already idle. So I guess the
> Session.StatusChanged signal for 'idle' is sent before the handler for
> that signal is registered via session.connect_to_signal. But I cannot
> connect to that signal before, because I need the session_path as return
> value of StartSession().
Yeah, there is a inherent race condition in dbus interfaces like this.
It is slightly annoying but you will need an initial GetStatus() call to
handle that. This goes for most signals in Syncevolution and elsewhere.
Most often you can just call the same function from signal handler and
after Get*()-call.
Ok, I just thought I was overlooking something. I worked around this as
you suggested, thanks.
So for the curious: Thanks to Jussi’s help, I have a basically working
re-designed Genesis in place. Just some cleanup to do and then I will
publish a first beta version.