Hello! 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.
To get started, let's summarize the current status: the D-Bus API is a 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: http://moblin.org/documentation/syncevolution/direct-synchronization-aka-syncml-server Jussi already filed some issues about the D-Bus API: dbus api should expose sync reports as hashtables http://bugzilla.moblin.org/show_bug.cgi?id=2061 dbus api modifications , GetSyncStatus() and signal http://bugzilla.moblin.org/show_bug.cgi?id=2412 dbus api modifications, move progress logic to server http://bugzilla.moblin.org/show_bug.cgi?id=2413 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 D-Bus. The other two are about a core principle of the D-Bus design: the D-Bus 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. For simple clients it makes sense to limit the user interface also to just one session. However, a client should be able to find the active session and adapt to the one which is currently running. 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 I think the difference between "actively doing something" and "waiting" 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 spinner" (http://bugzilla.moblin.org/show_bug.cgi?id=2229), 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 gears?). In the design for server I speculated that a session might be identified 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 several ways. 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 common/severe). 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 is all that I can think of for the UI<->D-Bus server interaction. 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 server side. In the meantime, I'll go back to the server design and write more about the D-Bus API required for that after clarifying some more aspects (in particular around OBEX). -- Best Regards, Patrick Ohly The content of this message is my personal opinion only and although I am an employee of Intel, the statements I make here in no way represent Intel's position on the issue, nor am I authorized to speak on behalf of Intel on this matter. _______________________________________________ SyncEvolution mailing list [email protected] http://lists.syncevolution.org/listinfo/syncevolution
