On Mi, 2011-12-21 at 17:17 +0100, Lukas Zeller wrote:
Digging though the case for a while, I suddenly realized that in
client case the implProcessItem() method used is the one in
binfileimplds.cpp and not the one in customimplds.cpp. However, we
added the 409 merge trick in customimplds.cpp only - no
wonder it "goes south" in the client case.
I'll check if I can easily add the same functionality to binfileimpds.
The reason why it is a separate method with seemingly duplicate
functionality is that binfileimpl is integrated tightly with the
binfile-based change log mechanism (even if you don't use it) - which
makes the implementation differ quite a bit even if functionality
provided is (i.e. in this case: *should be*) the same.
I've finally looked at this again, using the upstream gitorious repo's
master branch. That has your "DB_Conflict (409): added missing
implementation in binfileimplds.cpp" fix.
The sequence of events now is:
* dumb server has one item with UID=foo
* smart client has an updated version of that same item, created
there independently
* client and server sync:
* server stores two copies, then sends client the old copy
(ID 0) as "new item"
* client detects duplicate, resolves this internally by
keeping its own copy and returning 201 to the server
(instead of 409 as before); the <Map> sent to the server
maps the server's item 0 to the same LUID also sent to
the server as "new" from the client (stored there as
item 1)
* the server stores a UID mapping where its own old item 0
maps to the existing item foo on the client, and its new
item 1 maps to no item on the client
* client and server are now out of sync: the server still
has old and new copy of the item, the client only the
new one
* client and server sync again:
* client sends its copy as "updated"
* server updates its old copy
* client and server are still out of sync: one item too
many on the server
I'm not sure how to fix this. When processing the <Map>, the server must
have detected that the same client ID was used twice. What it logs at
the moment is this:
[2012-01-30 18:01:19.775] Mapping remoteID='foo' to localID='0'
[2012-01-30 18:01:19.775] file_calendar: testState=TRUE - expected
state>='sync_mode_stable', found state=='sync_gen_done'
[2012-01-30 18:01:19.775] ModifyMap called: aEntryType=normal, aLocalID='0,
aRemoteid='foo', aMapflags=0x0, aDelete=0
[2012-01-30 18:01:19.775] - found entry by entrytype/localID='0' -
remoteid='', mapflags=0x0, changed=0, deleted=0, added=0, markforresume=0,
savedmark=1
[2012-01-30 18:01:19.775] - matching entry found - re-activating deleted and/or updating
contents if needed
[2012-01-30 18:01:19.775] - cleanup: removing same remoteID from other entry with
localid='1', mapflags=0x0, changed=0, deleted=0, added=0, markforresume=0,
savedmark=0
[2012-01-30 18:01:19.775] Map entry updated: LocalID='0', RemoteID='foo'
Should it have removed one item while processing the <Map>?
IMHO it can't, because it doesn't have enough information to determine
which of its two items are up-to-date. It only knows that the client
must have merged two items, but not yet which one won.
In the second session, the server gets an updated item with client ID
"foo". Now it could update one copy and delete the other, but because it
only kept a link between its item 0 and foo, it only does the update
part.
Would something break if the server allowed the same client item to map
to multiple items on the server and then did a remove in its database
when receiving an update?
I suspect that the client is simply doing something not expected by
typical SyncML servers. Here's what other SyncML servers do:
* Memotoo: doesn't send UID in its item data, thus the client does
not detect the duplicates
* Funambol: doesn't let me run a sync at the moment, need to test
later
--
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.