[sync] Turba and Syncml patch proposal

Karsten Fourmont fourmont at gmx.de
Sat Jan 8 06:49:53 PST 2005


Quoting Chuck Hagenbuch <chuck at horde.org>:

> The client addressbook should *not* be used as the default. There is a
> default_dir preference in Turba; that would be a reasonable default.

OK, I'll use that.

>> 2) the _import functions now return a plain UID. However the history
>> functions still require a "extended" guid like "memo:karsten:xxxx". This
>> is a bit of a fracture: most API functions deal with plain UIDs, but
>> when calling the /listBy Api function, I get an "extended" guid (as it
>> comes from the datatree).
>
> That should be fixed in the listBy functions, then.

OK. I can change this either in $history::getByTimestamp or just in the api
listBy functions of the respective apps. I'd prefer the later: history is used
throughout horde, changes there would have a big impact.

So I propose to change the listby function in the api as follows. Instead of
returning the extended guis with
    return array_keys($histories);
they'll return only the plain uid with something like

    return preg_replace('/^([^:]*:){2}/', '', array_keys($histories));

>> This is an issue for SyncML: after adding a
>> new entry to the Horde Database, Syncml needs to get the log timestamp
>> for that action. We need that as we have to manually remove these
>> entries from /listBy results to avoid duplication by echoing back new
>> entries to the client. However /import now returns only a plain guid and
>> I can't feed this to the history object (for timestamp retrival) unless
>> I add a prefix like 'turba:karsten:'. But this would be a bad solution:
>> SyncML deals with the external API and only knows 'contacts', not 'turba'.
>
> Why do you need the timestamp to filter out the uid?

The reference timestamp for the sync is agreed upon be client and server during
the initalization of the sync.
Let's call the timestamp for the previous sync t_0 and the one for the current
sync t_1.
Sync for t1 starts. Timeframe is t_0 < t < t_1. The client sends a "modify" for
an adress book entry X at time t with t_0 < t_c < t_1.
The server (horde) then does this changes in the horde backend. The change in
the server gets a timestamp t_s with t_s > t_1.
After client request have been processed is's the servers turn to sends its
changes back to the client. A horde history call returns the recent server
change X as well. But the timestamp is t_s > t_1 and so the horde sync module
knows that this change must not be included for period t_0 < t < t_1.

But now consider the next sync session. Here the reference period is t_1 < t <
t_2. The history call returns the client inducted modification X at t_s with
t_1 < t_s < t_2 matching the reference period. The server can't know it came
from the client orginially and so sends this as a modify request to the client.
This is wrong.

So SyncML stores the timestamp for a client inducted change on the server side
in its internal map. So it can see if a specifig change came from the client
and thus must not be sent back to the client.

So I need to get the timestamp of a given operation.

>> So what I did is this: History gets a getLastLoggedTS() functions that
[does evil things]
>> Is it OK to commit this or is
>> my history modification too bad a hack?
>
> That is definitely too much of a hack; please don't commit it.

That's why I was asking. :-) Agreed.

As I explained above, we do need a way to retrieve the timestamp of a given
operation. So we'll go back to the old getTSForAction() way. But it's cleaner
to have it in the api. So I'd like to add a new api function. Something like

function getTSforAction($uid, $action)
{
    require_once 'Horde/History.php';
    $history = &Horde_History::singleton();

    $guid= 'turba:' . Auth::getAuth() . ':' . $uid;

    return $history->getTSforAction($guid, $action);
}

same for kronolith and mnemo. Is the name OK? Maybe just "getTS"?

With these two changes to the api (modify listBy, add getTSforAction), we should
be doing fine:

1) the external API only deals with plain uids. Not at all with extended guids
used and returned by the history functions
2) SyncML does not directly call history anymore. Everything is just done using
the external API.

Some comments or a confirmation on that would be nice. Until that I'll wait with
the coding. I don't want a third patch proposal from me getting blown to pieces
:-) But I think it was worth the effort.

Karsten



More information about the sync mailing list