Patrick Ohly wrote:
I promised Jussi and Frederik that I would down some thoughts about the
next incarnation of the D-Bus API. As you can imagine, I was busy with
0.9 beta 3, and therefore haven't had the time yet.
I'm leaving for Tallinn early tomorrow morning so won't get much in to
details now (need sleep). I will copy my notes on future UI work here,
because they are slightly related -- I wrote this before seeing you mail
so there's some repetition. This is just a stream of possible work items.
See my comments on your mail below this.
1 Minor DBus api improvements (lessons learned in the last six months)
- Fix some remaining bugs (mostly get the sync reports out properly)
- make sure we are ready for automatic syncs (see 3 & 4)
- This is a must have, it's just been more difficult than
I expected. I'll follow up with another mail on this.
- Question: Can we get data on local database contents?
2 minor UI improvements:
- implement some missing features (such as a discoverable way of
getting out of Settings)
- actually use the gtk widgets from nbtk library (atm we use our own
- make sure the plain gtk UI does not get broken because of these
3 move some sync progress logic into the server
- if we want to report progress in similar ways in several UIs (e.g.
sync-ui and notifications), some logic should be moved to server
4 handle rejections / conflicts in the UI
- ideally the problematic data item would be shown to the user and
would be a way "undo" a wrong conflict resolution or fix the
rejection reason (maybe by opening the item in
- Question: how difficult is it to get the problem "item" from EDS
based on the info we have?
5 implement automatic syncing
- sync without user interaction at interval
- sync when local changes happen, if possible
- libnotify notifications on sync progress/success/failure
(no notifications when sync ui is visible?)
- Ideally the notifier would know when a UI is open and would not
start automatic syncs then
- I have no idea yet where and how this should be implemented...
6 Improve UI so automatic syncs make sense
- we need to expose more sync history, at least in some way to show
what has happened "automatically", and even more importantly what
failed to happen...
- this very much relies on the sync report api being useful
- Nick did some wireframes of this, I'll 'dissect' those when I get
To get started, let's summarize the current status: the D-Bus API
private API between syncevo-dbus-server and the sync-ui. It has the
features that were needed, but is not complete yet. Anyone using it has
to be aware that it can (and will change).
We need to stabilize the API and make it more generally useful. In
addition, it needs new functionality to implement the server stubs
mentioned in the design of the next-generation SyncEvolution:
Jussi already filed some issues about the D-Bus API:
dbus api should expose sync reports as hashtables
dbus api modifications , GetSyncStatus() and signal
dbus api modifications, move progress logic to server
The first one is an implementation detail. The C++ SyncReport class
covers basically everything which can be said about a sync session,
ranging from statistics to success/failure information. New information
may get added, so we need a backwards-compatible way of sending it over
Yes, it makes sense to make the Report a Hashtable something similar
that can contain data that may change (or at least grow) in new
versions. The reason this isn't done yet, is that I had trouble making
an API that would both have sane function signatures (not too many
nested data structures) and that would not require multiple calls for
The other two are about a core principle of the D-Bus design: the
server runs sessions, D-Bus clients view results and/or control the
sessions. We are not there yet, currently the sync-ui contains quite a
bit of logic.
I've mentioned sync sessions. We should design the API so that more than
one session can be active at a time even though right now, the server
cannot run more than one at a time. Changing that would be both hard
(there are some global instances, for example logging; the
EvolutionSyncClient API takes control while a session runs) and provide
little benefit (only one session should modify local data at a time).
The server has to enforce that only one session runs at a time, which
could be done by queuing requests.
This shouldn't be that difficult from the API point of view. Every
session should be a new D-Bus object and the object path is announced in
a NewSession signal in the main syncevolution object.
This does make simple client implementations more complex. I have some
ideas on this though, I'll get back to this.
For simple clients it makes sense to limit the user interface also
just one session. However, a client should be able to find the active
session and adapt to the one which is currently running.
the mentioned signal plus a GetSessions() should do, I guess.
The information about a session must include:
* configuration, using well-known names that can be presented to
the user (current usage model)
* peer information, for server configurations that define local
databases that other devices connect to (new server mode)
* a flag to distinguish between these two different configurations
* executing/waiting for IO/completed state, including signals when
the state changes
* session can be started/suspended: it should not be possible to
start a session unless the transport is up and/or the peer is
present (Bluetooth). We might want to disallow suspending if we
know that the peer doesn't support it.
* progress information
* sync report when session is finished
I think the difference between "actively doing something"
is relevant. A sync session can hang for a long time without any
progress update when a HTTP server or the network are slow. As I said in
"UI needs a progress
), the spinner
should only be active when the client is waiting, not when it is doing
something. If we want to be really fancy, we could spin a "waiting for
IO" animation while waiting and something else while processing (turning
I'm not sure about this. As a user I just want to know things are
happening, I'm not really interested in what detail is going on (to that
level of detail)... I imagine it would be enough to add a "waiting"
state to the Progress signal we already have?
In the design for server I speculated that a session might be
with the configuration name. I think I would prefer a more abstract
handle. That way we can use the handle to refer to historic sessions of
a particular configuration.
Another update on the design is the handling of "server configurations".
Originally I wanted to keep the current concept of "one peer, one
configuration" because it allows us to keep the current file layout
(config.ini + .synthesis + .internal.ini). But this is problematic in
First, it requires that the peer is known before we initialize sources
and the Synthesis Engine. The peer is identified inside the SyncML
message and only becomes available to SyncEvolution as part of the
session initialization inside the Synthesis Engine. This is a
contradiction which would have required peeking into the message.
Second, it duplicates the configuration information. Third, database
dumps become harder to find (but that is also a problem with one server
configuration and one client configuration, albeit perhaps less
Therefore I think we'll have to change the file layout and the internal
APIs so that SyncSources can be instantiated before the engine, but then
get access to per-peer files only later after the session has started.
The file layout has to be changed accordingly. The .synthesis directory
can be shared between peers, the Synthesis Engine takes care of tracking
which information belongs to which peer.
Coming back to the D-Bus client/server communication. I think it would
be useful to pass a stream of log messages from the server to the
client(s). These log messages are by design not translated, so they
should only be shown to advanced users. With this in place we could
change the command line client so that it uses the server instead of
calling libsyncevolution directly.
For normal users, the information provided by the server in addition to
this raw text must be rich enough to generate localized messages. This
can be difficult ("Can not do sync from GUI, and error info is
inconsistent with commands", #4660, "Synthesis error codes and
explanation", #2069). Right now, the D-Bus API directly passes through
Synthesis event codes. We might have to add and document our own
intermediate translation of these events.
In addition to reading and presenting information, there is also a
variety of operations that controllers need to do:
* start a session
* create and update configurations
* browse and restore data from the backups
* parse and execute command line parameters (so that the
"syncevolution" command line tool really is just a main()
function with some D-Bus code, unless it is compiled in the
traditional "call local class" mode)
This last point may be tricky (I really don't know), the original api
design was based on "what am I going to need for a simple UI", there may
be some more complex corner cases hidden in there -- syncevolution is a
pretty versatile beast...
On one hand it would ensure the api is complete, but it might still
not be worth the trouble -- especially if you plan to keep the non-dbus
mode as well. We'll see.
This is all that I can think of for the UI<->D-Bus server
Did I forget anything? Any comments?
Jussi, do you think you can take over this part of the discussion,
compare it against the current D-Bus API and propose the next revision
of it? That doesn't mean that you have to implement all of it. We could
split it so that you concentrate on the GUI and someone else does the
Yeah, I'll post something on week 32.