On Wed, 2009-12-30 at 13:07 +0100, Ove Kaaven wrote:
Patrick Ohly skrev:
> Looking at the code again and in particular
> SyncSourceRevisions::updateRevision(), I remembered one problem with the
> "changes since last sync" approach of change tracking. Suppose the
> following chain of events:
> 1. sync starts at time T1, with no local changes
> 2. a changed item A is sent by the SyncML server and updated
> 3. the user edits a different item B while the sync runs
> 4. sync ends at time T2
> Now in the next sync, which time stamp should be used to find changed
> items that need to be sent to the server?
> When using T1, the changed item A would be sent to the server, which is
> wrong (additional traffic, unnecessary risk of conflicts on the server).
> When using T2, the locally modified item B would not be sent.
> Updates of the database would have to be disabled while a sync runs to
> avoid this problem. Is that possible?
I don't think so. I think this is why I originally was talking about
improving on TrackingSyncSource, not about replacing it; then I could
make the backend retrieve all IDs modified after time T1, and then
TrackingSyncSource would check which of these IDs has already been
synced the same way as it currently does.
Yes, this should work. You can reuse the revision recording in
SyncSourceRevisions, but instead of of calling
SyncSourceRevisions::detectChanges(), you would have to implement and
invoke your own method and report the result via
SyncSourceChanges::addItem() calls for new/updated/deleted/existing
items. In other words, you replace the change tracking logic in
SyncSourceRevisions/TrackingSyncSource while reusing some of the
You still need to store a "last sync" time stamp. This is a property
that is not currently recorded, but could be added. Have a look at
SyncConfig.h/cpp and an existing property like sourcePropPassword
(per-source property) and syncPropMaxMsgSize (unsigned long value, which
might be the right type for a time_t).
I'd expect that to still be
much faster than checking every ID in the whole database.
There's another reason why all items are read once: dumping a snapshot
of the current database content. This is called via a SyncSource API
which is independent of change tracking and therefore currently all
items are read twice - something that we definitely want to improve.
This could be done in the current SyncSourceRevisions by reading all
items when requested for the backup and while doing that, remember the
UID/revision string pairs for later use in detectChanges().
So suppose that we have efficient change tracking that works without
reading all items. Should the backup mechanism "trust" the change
tracking and try to "update" an older backup?
On a desktop system, taking a snapshot is fast, so it is done via the
brute-force approach. This has the advantage that bugs in the change
tracking (caused by our own code or the underlying libraries) are found.
On a mobile device a more intelligent approach might be better.
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.