Patrick Ohly changed bug 70950
What Removed Added
Blocks   72112, 72114

Comment # 1 on bug 70950 from
Here's a proposal for the PIM Manager API. This also includes enhancements for
suspend/resume (bug #72112) and enhanced progress (bug #72114).

The additional paragraphs about "a peer can have
only one running sync at a time" and "same contact gets counted twice" do not
change the API. They are merely clarifications.

diff --git a/src/dbus/server/pim/pim-manager-api.txt
index 3283c7c..97128ca 100644
--- a/src/dbus/server/pim/pim-manager-api.txt
+++ b/src/dbus/server/pim/pim-manager-api.txt
@@ -51,6 +51,10 @@ address book. That information is passed via D-Bus as a
 string-to-string dict, with keys and their values being defined by the

+For the sake of API and implementation simplicity, a peer can have
+only one running sync at a time. The API uses the peer ID for
+information about such a running sync (see "SyncProgress" signal).
 Address books

@@ -254,12 +258,45 @@ Methods:
          updated. The caller needs to check the local cache to find out
          what it contains.

+    dict SyncPeerWithFlags(string uid, dict flags)
+         Same as SyncPeer() with additional control over the sync via
+         optional flags. The flags and their values are
+         implementation-dependent.
     void StopSync(string uid)

          Stop any running sync for the given peer. The SyncPeer() method
          which started such a sync will return with an "aborted" error
          once the sync was stopped.

+    void SuspendSync(string uid)
+         Suspend any running sync for the given peer. The SyncPeer()
+         method which started such a sync will continue to run. If
+         suspending is not possible for some reason, the sync will
+         automatically abort or fail (depending on the peer). It is
+         okay to suspend twice. Suspend and resume calls are not
+         nested, so a suspended sync resumes after one ResumeSync(),
+         regardless how often SuspendSync() was called.
+    void ResumeSync(string uid)
+         Resume a previously suspended sync. It is not an error to call
+         this when there is no sync running or it was not suspended.
+    dict GetPeerStatus(string uid)
+         Returns information about the peer and its sync status. The returned
+         dictionary contains:
+         "status": string "idle", "syncing", "suspended" - describes whether
+         a sync is currently running. Idle means "no active sync"; there might
+         be a pending SyncPeer().
+         Implementations can also provide information similar to the data
+         provided by the SyncProgress signal.
     dict of UID to string key/value dict GetAllPeers()

          Returns information about all currently configured peers.

diff --git a/src/dbus/server/pim/README b/src/dbus/server/pim/README
index a83fe52..c444c40 100644
--- a/src/dbus/server/pim/README
+++ b/src/dbus/server/pim/README
@@ -326,8 +326,9 @@ Not supported via the API at the moment:

-SetSync() in SyncEvolution will return a dict with all of the
-following entries set:
+SyncPeer() and SyncPeerWithFlags() in SyncEvolution will return a dict
+with all of the following entries set:
     "modified": boolean - data was modified
     "added" : integer - number of new contacts
     "updated" : integer - number of updated contacts
@@ -337,14 +338,66 @@ In other words, the caller can reliably detect when
nothing changed,
 but when contacts were modified or added, it needs to read them to
 determine which kind of properties were modified or added.

+It is possible that the same contact gets counted twice, for example
+when adding it in the first text-only cycle and later updating it with
+photo data in the second cycle, or updating some text first and the
+photo later.
+Additional control over syncing is possible via the flags dictionary
+in SyncPeerWithFlags(). The following keys are possible:
+    "progress-frequency": float - desired frequency in Hz (= events
+    per second) of the SyncProgress "progress" event. Default is 1/s.
+    "pbap-sync": string "text"|"all"|"incremental" - synchronize only
+    text properties, all properties or first text, then all.
+When doing text syncing, local photo data is preserved. The
+incremental sync has the same effect as a text-only sync followed by
+an all-properties sync. The only difference is that it looks and
+behaves like a single sync of the peer.
 The SyncProgress is triggered by SyncEvolution with three different
 keys (in this order, with "modified" occuring zero or more times):
-  "started" "modified"* "done"
+"started" ("modified" | "progress")* "done"

 "started" and "done" send an empty data dictionary. "modified" sends
-the same dictionary as the one returned by SyncPeer(), if contact data
-was modified. So by definition, "modified" will be True in the
-dictionary, but is included anyway for the sake of consistency.
+the same dictionary as the one returned by SyncPeer(), if and only if
+contact data was modified. So by definition, "modified" will be True
+in the dictionary, but is included anyway for the sake of consistency.
+"progress" sends the same dictionary as "modified" with one additional
+    "percent": float - value from 0 (start of sync) to 1 (end of sync)
+"progress" is guaranteed to be emitted at the end of each cycle. In
+contrast to "modified", it will also be sent throughout the sync *if
+and only if* progress has been made, regardless whether that progress
+led to contact data changes or an increase in the completion
+percentage. That way, the event also serves as a heartbeat mechanism.
+The completion percentage is based purely on the number of contacts on
+the peer, which is the only thing known about the peer at the start of
+a sync. In a simple sync involving just one cycle, the percentage is
+"number of processed contacts / total contacts".
+In a sync involving two cycles, it is "number of processed contacts /
+2 / total contacts". Because each contact gets processed once per
+cycle, that gives 50% completion at the end of the first cycle and
+100% at the end of the second.
+Note that progress will not be linear over time even for a simple
+sync, because some contacts will take more time to download and
+process than others. For an incremental sync, the first cycle is
+likely to be much faster than the second one because the second one
+includes photo data.
+GetPeerStatus() returns two additional entries in the dictionary:
+    "progress": same dictionary as the SyncProgress "progress" value
+    "last-progress": float - time in seconds since the last "progress"
+    event. This is included to let a polling client determine whether
+    the sync is still alive.

 Contact Data

You are receiving this mail because: