On Mon, 2012-11-05 at 19:48 +0100, Patrick Ohly wrote:
On Fri, 2012-10-26 at 21:04 +0200, Patrick Ohly wrote:
> I'm attaching the current API revision, a README which gives
> SyncEvolution specific information and two example scripts.
I realized that the API has a conceptual problem that makes it a bit
harder to use; I didn't get it right in the example "search.py".
Right now, search.py calls ReadContacts each time it is told that new
contacts were added or old ones updated. It does the call for exactly
the affected contacts. The goal is to always have the actual contact
data, as soon as possible.
The problem is that ReadContacts() is defined as returning the contacts
in the requested range *at the time when the server processes the call*.
[...]
The other solution is to change the API as follows:
- Introduce a separate string ID for a contact.
[...]
- The string ID becomes part of the contact dictionary:
- Change the ReadContacts() call so that it takes an array of these IDs
to determine which data is requested:
[...]
I've implemented this. Code is currently pending further testing (and
perhaps review - does anyone want to comment?) in the for-master/pim and
pim branch. Here's the final API change (I added some more explanations
and adapted all notifications):
commit 3a6574eb030a5f655e0e59f5445906c811ea188d
Author: Patrick Ohly <patrick.ohly(a)intel.com>
Date: Thu Nov 8 17:02:16 2012 +0100
PIM API: introduce string ID for contacts
This simplifies writing clients which want to read all new or modified
contacts. Previously, with just a range being used in ReadContacts(),
the client had to be prepared to re-issue reads when changes to the
range happened on the server before the request was processed.
The ViewAgent notifications all take IDs. For added contacts the need
is obvious. For modified contacts it comes from the situations where
one contact replaces another. This was already possible before, so the
comment about "temporarily appear at two different positions" merely
documents existing behavior. Removal notifications include the ID
primarily for consistency with the other notifications. It was also
already useful for debugging.
diff --git a/src/dbus/server/pim/pim-manager-api.txt
b/src/dbus/server/pim/pim-manager-api.txt
index fbe2f62..27c0f1e 100644
--- a/src/dbus/server/pim/pim-manager-api.txt
+++ b/src/dbus/server/pim/pim-manager-api.txt
@@ -89,6 +89,8 @@ FolksIndividual:
- "source" = list of string pairs, where each pair is a combination
of address book ID and local contact ID inside that address book
(not necessarily the same as the vCard UID of a contact!)
+- "id" = an opaque string which identifies the contact while it
+ exists inside any PIM Manager view. See ContactsAdded and ReadContacts.
Property values which are large (like photos) are not sent via
D-Bus. Instead a link to a local file is sent.
@@ -359,20 +361,26 @@ Interface: org._01.pim.contacts.ViewControl
Object path: [variable prefix]/{view0,view1,....}
Methods:
- list of contact dicts ReadContacts(int start, int count)
+ list of (int index, contact dicts) pairs ReadContacts(array ids)
- Requests at most "count" contacts in the view, starting
- with the one at "start" (numbered starting with 1). May
- return less (or no) contacts if the request range is
- beyond the end of the view at the time when the call is
- processed.
+ Requests the data of the contacts idenfified via their IDs.
+ Only the data of contacts that are still part of the view
+ can be returned.
- Note that the caller must process the call response
- after all events via the ViewAgent interface if it wants
- to keep in sync with the view. Doing this call asynchronously
- and dealing with the response as part of the main event
- loop will do the right thing automatically, because D-Bus
- guarantees ordering of messages.
+ The returned list contains the current index of the
+ requested contact plus its data. -1 and an empty
+ dictionary are returned for contacts which can no longer
+ be read, for example because they were removed from the
+ view in the meantime or because the ID was simply
+ invalid.
+
+ Note that the caller must process the call response after
+ all events via the ViewAgent interface. Otherwise the
+ index numbers are potentially out of sync and thus
+ unreliable. Doing this call asynchronously and dealing
+ with the response as part of the main event loop will do
+ the right thing automatically, because D-Bus guarantees
+ ordering of messages.
Making this explicit by returning data via another
org._01.pim.contacts.ViewAgent method was considered and
@@ -401,23 +409,40 @@ Object path: [as chosen by user of PIM Manager]
Methods:
- void ContactsModified(object view, int start, int count)
+ void ContactsModified(object view, int start, array ids)
Contacts #start till #start + count (inclusive) have
changed. Data that the recipient of the call might have
- cached became invalid and should be reloaded. In cases
- where changing a contact changes its position in the
- sorted list, "contact removed" and "contact added"
- notifications will be triggered instead of a "contact
- changed".
+ cached became invalid and should be reloaded.
+
+ It is possible that a contact gets replaced by another
+ with a single "contact modified" signal. In other words,
+ the ID at each position may change and thus the IDs
+ are sent as part of the signal.
+
+ In cases where a contact changes its position in the
+ view, both a combination of "contact removed" + "contact
+ added" (single contact changes) as well as several
+ "contact modified" signals are possible (contacts swap
+ position, for example when reordering).
+
+ In the later case, a contact will temporarily appear
+ at two different positions.
+
+ void ContactsAdded(object view, int start, array ids)
- void ContactsAdded(object view, int start, int count)
+ New contacts were added to the view. The number
+ of new contacts is given via the size of the ids array.
+ The ID of each new contact is guaranteed to be the same
+ in all views. IDs may get reused after their contact got
+ removed from the last view it was contained in. In
+ particular there is no guarantee that it is persistent
+ across restarts of the PIM manager.
- New contacts were added to the view.
The contact which previously had index #start now
has index #start + count, etc.
- void ContactsRemoved(object view, int start, int count)
+ void ContactsRemoved(object view, int start, array ids)
Some contacts were removed from the view.
The contact which previous had index #start + count
--
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.