mehov / mooha

Automatically exported from code.google.com/p/mooha
1 stars 0 forks source link

Wrong anchor sent to client #20

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
When using mooha with SyncEvolution, SyncEvolution switches to slow sync on the 
second sync attempt, because the Anchor that mooha sends in its "<Last>" tag 
does not match the anchor previously sent in the "<Next>" tag.

This happens (only?) when the first (or at least previous) sync attempt is 
succesful, but no data is sent from the client to Mooha. This causes none of 
the item_anchors to be updated. However, on the next sync, Mooha sends the 
maximum of the item_anchors in the database to the client in the <Last> tag, 
but that does not match the anchor previously sent in the <Next> tag. The 
latter is stored in the server_anchor.

Looking at the code, it seems the following line in MoohaServer.php in 
_buildAlert (around line 1229, but I have some local modifications) is guilty:
                        $alert->Item->Meta->Anchor->addChild('Last', $this->_getDatabseAnchor($_SESSION['moohaUserId'], $dbId));

Changing this to "_getServerAnchor" fixes this particular problem. It also 
seems more logical, to actually use the anchor previously sent in <Next> (which 
was saved to the server_anchor by _saveSync.

Original issue reported on code.google.com by matthijskooijman@gmail.com on 31 Aug 2010 at 12:25

GoogleCodeExporter commented 9 years ago
Some more testing shows that this solution isn't ideal either: Mooha only 
updates the server anchor when items have actually been sent to or received 
from the client. With the change I proposed, this causes errors after every 
sync attempt where nothing has changed.

Simply updating the anchor after every succesful sync seems to make sense, and 
is also what the specs suggest AFAICS. However, Mooha compares the server 
anchor with the database anchor (the maximum timestamp from all of the database 
items) using the inequality operator: So if the server anchor is newer than all 
of the item anchors, this will cause the server to generate an (empty) Sync 
command. This is of course easily fixed by replacing this comparison by a 
$serverAnchor < $databasAnchor.

Even so, I think this problem (empty Sync elements) will occur anyway, since 
when the server anchor is actually updated, it is set (through the 
moohaServerAnchor_* session variables) to the current time (by _createAnchor), 
which will probably never match the database anchor exactly.

An alternative approach could be to use the database anchor as the new server 
anchor, if it is newer. This would probably also solve the above problems.

I'm not sure about the implications of either approach, so I'll leave the 
actual fix to others :-)

Original comment by matthijskooijman@gmail.com on 31 Aug 2010 at 2:48

GoogleCodeExporter commented 9 years ago
Hi,
How did you see this tag error ? Do you have some information in the error log 
? As i make a synchronisation with Thunderbird, I get an error but I can't know 
what type of error it is because no information is logged in error file.

Original comment by kloryd...@gmail.com on 31 Aug 2010 at 2:53

GoogleCodeExporter commented 9 years ago
The alternative approach would be to replace:

    $_SESSION['moohaServerAnchor_' . $dbId] = $this->_createAnchor();

with

    $_SESSION['moohaServerAnchor_' . $dbId] = $this->_getDatabaseAnchor($_SESSION['moohaUserId'], $dbId);

However, quick testing shows this isn't enough: When receiving updates from a 
client, the moohaServerAnchor_* variable is also used to update the 
item_anchor. When updates are received from the client, the item_anchor on 
those updates should be the current time. This also means that the server 
anchor should be at least the current time, to prevent this particular client 
from getting his own updates again on the next sync run.

But, when we need to decide the <Next> anchor, when creating the <Alert> 
command, it is not known yet whether the client will send any updates. So the 
best thing we can do is always send the current time in the <Next> anchor, but 
then we must also take care to always update the server anchor, even when no 
updates are sent either way.

Original comment by matthijskooijman@gmail.com on 31 Aug 2010 at 3:03

GoogleCodeExporter commented 9 years ago
This error shows up when using SyncEvolution. It keeps track of the <Next> 
anchor in each sync session and compares it with the <Last> anchor in the next 
session. If there is a mismatch, then apparently something went wrong in the 
last session, and it starts a slow sync to make sure that everything is 
corrected. This is an excerpt from the SyncEvolution log:

> Saved Last Remote Server Anchor='1283265135', received <last> Remote Server 
Anchor='1283264889' (must match for normal sync)
> Switched to SlowSync because of Anchor mismatch or server-side user option

This is exactly how the specs intended anchors to work, see section 2.2.1 of 
the SyncML Sync protocol spec:

> If the device stores the Next sync anchor, it is able to compare during the 
next synchronization whether the sync anchor is the same as the Last sync 
anchor sent by another device. If they are matching, the device is able to 
conclude that no failures have happened since last sync. If they are not 
matching, the device can request a special action from another device (e.g., 
slow sync).

Original comment by matthijskooijman@gmail.com on 31 Aug 2010 at 3:08

GoogleCodeExporter commented 9 years ago
Hi matthijskooijman,

do you have some "complete" resolution for this error? You wrote a lot of 
possibilities and I'm not sure, if I have to done them all or something else.

Thanks for response :)

Original comment by ludvikto...@gmail.com on 9 Feb 2011 at 3:46

GoogleCodeExporter commented 9 years ago
Considering I'm not longer using Mooha, I can't provide you with an actual 
patch or complete plan. However, from reading back my notes, I think I can 
provide a conclusion on how things should work. I think that solving this 
properly will require quite some changes in the Mooha anchor handling code, you 
might want to completely rethink all of the anchor handling, instead of trying 
to fix this with just one or two code changes.

Anyway, I think this is what should happen:

1. At the start of a session, generate the "next" anchor. This should just be 
the current time.
2. In the Alert command, send the stored anchor as the "Last" anchor.
3. When items are received from the peer, use the generated "next" anchor as 
their new anchor.
4. When deciding which items to send to the peer, compare the stored anchor 
with every item anchor, sending over those whose item anchor is newer.
5. After a successful session (even when no sync commands were sent!), update 
the stored anchor with the "next" anchor generated for this session.

If anything is still unclear, feel free to ask.

Original comment by matthijskooijman@gmail.com on 10 Feb 2011 at 9:23

GoogleCodeExporter commented 9 years ago
Thanks for response, I'll take eye on it asap.

One question I have: why are you no using Mooha? Did you find better sollution? 
Because I have big problems with this, but it's only PHP project I found.

Original comment by ludvikto...@gmail.com on 15 Feb 2011 at 10:06

GoogleCodeExporter commented 9 years ago
I'm now using the SyncEvolution HTTP server. It's a standalone daemon, not a 
PHP solution, but that worked for me as well. Considering I was also using 
SyncEvolution at the client side, it made sense to use it server side as well. 
I might have another look at Mooha later on, but for now, I have a working 
SyncEvolution setup...

Original comment by matthijskooijman@gmail.com on 15 Feb 2011 at 10:12