I've been trying to get evo to sync with sync4j (syncml) with Multisync
for a while now, and it's finally worked (once). Much of the frustration
seems due to sync4j issues, but some of it is the evo2 plugin's fault,
and I'll brain-dump to the list for posterity while I try to make my
Razr talk to sync4j.

Anyway.

Firstly, the evo2 plugin in CVS HEAD appears to be ridiculously broken,
so after a while spent making it compile, I switched back to the 0.82
base. No idea what was going on in there, but I had too many other
variables to worry about.

The evo2 plugin in 0.82 appears not to support slow sync (full
resyncing). It never looks at the newdbs arg passed into get_changes.
The only reason that it ever works is presumably somewhat accidental;
the first time evolution sees it attempt to sync, it will dump out the
whole database, and after that, only the changes.

The way evolution identifies a sync peer, just by the way, is by a
rather misleadingly named "change_id" parameter passed in via the
appropriate transactions. It then maintains a separate image of the
requested database for this "change_id", and on sync, returns the
changes required to bring it up to date to the reference database, and
immediately applies them.

This means that if you run the evo sync functions twice with the same
change_id, the second one is guaranteed to return no changes. No ifs,
buts or maybes; if you discard the first set of changes, you lose data.

A couple of interesting impacts from this. Firstly, the syncml plugin
will attempt to re-fetch the changes if requested to do a slow sync.
This fails miserably for the above reason.

Secondly, because the change_id is statically generated from the
datapath, if you delete and re-create the pair in multisync, you *still*
get no changes... until you create the pair in a slot that hasn't been
used before. Very silly (and most easily fixed by deleting the state
files under ~/.evolution).

Anyway. My quick fix was to regenerate the change_id whenever a slow
sync is requested (patch attached).

Because the change_id isn't actually saved to settings, this is likely
to misbehave and issue duplicate changes when multisync restarts, but it
works for my purposes right now and I'm lazy.

Obvious work to improve this further seems to be:
* save change_id to settings
* track separate change_ids for each database type

Then the next trick is to probably to simulate a get_changes/commit
two-phase thing in the evo2 plugin, which is likely to be quite nasty.

m.
--- evolution2_sync/src/evolution_sync.c.~1~    2005-04-01 11:38:45.000000000 
+1000
+++ evolution2_sync/src/evolution_sync.c        2005-04-08 11:49:54.000000000 
+1000
@@ -213,6 +213,12 @@
        GList *chinfo_list = NULL;
        sync_object_type retnewdbs = 0;
        
+       if(newdbs) {
+         printf("slow sync requested, old change_id %s\n", env->change_id);
+         env->change_id = g_strdup_printf("slowsync-%s-%d", 
g_path_get_basename(sync_get_datapath(env->handle)), time(NULL));
+         printf("changed to change_id %s\n", env->change_id);
+       }
+
        if (env->adressbook && env->commondata.object_types & 
SYNC_OBJECT_TYPE_PHONEBOOK) {
                if (!e_book_get_changes(env->adressbook, env->change_id, 
&changes, NULL)) {
                        sync_set_pair_status(env->handle, "Could not get 
changes from addressbook");

Reply via email to