Ticket #1161 (closed task: fixed)
[API] Add osync_context_report_uid_update(OSyncContext *ctx, const char *olduid, const char* newuid) for sync_done() phase
| Reported by: | dgollub | Owned by: | dgollub |
|---|---|---|---|
| Priority: | highest | Milestone: | OpenSync 0.40 |
| Component: | OpenSync: Plugin API | Version: | 0.39 |
| Severity: | critical | Keywords: | |
| Cc: | gcobb, bellmich, dgollub, tuju |
Description
Introduce new plugin context function for plugin-sink function/phase sync_done():
OSYNC_EXPORT void osync_context_report_uid_update(OSyncContext *ctx, const char *olduid, const char *newuid);
This function should allow plugins to update the UID of changes in the persistent (intenral) mapping table of OpenSync?. During the sync_done phase.
Usecase
- SyncML protocol requires that after all changes got committed to the SyncML-peer-device to handle a <Map> command
- This <Map> command is optional
- <Map> contains a old UID/MappingID and a new UID/MappingID of a change
- OpenSync? needs to update it's internal mapping to this new UID/MappingID
- This <Map> can also appear on the next sync of a change/commit of a previous sync!
- Needs to be independent of a OSyncChange object!
- A <Map> command with the same information/UIDs can be send multiple times
- requires additionally handling when updating the mapping table
- no error if the mapping got already updated
- error if old and new UID can't be found at all in the mapping table
- requires additionally handling when updating the mapping table
Mapping Table update issue
To handle OSyncChange object independent UID updates this might require that we have a "backup" of the original UID in the mapping tbale. Current the table looks like this:
CREATE TABLE tbl_changes (objtype VARCHAR(64) NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT, uid VARCHAR NOT NULL, memberid INTEGER NOT NULL, mappingid INTEGER NOT NULL, objengine VARCHAR(64) NOT NULL );
Michael suggested to add a new column, which stores the original reported UID:
CREATE TABLE tbl_changes (objtype VARCHAR(64) NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT, uid VARCHAR NOT NULL, orig_uid VARCHAR NOT NULL, memberid INTEGER NOT NULL, mappingid INTEGER NOT NULL, objengine VARCHAR(64) NOT NULL );
(Maybe this can be avoided? Needs to be figured out ...)
Without a "backup" of the orignal UID there could be following problem:
Following entries get reported in commit() function of syncml plugin:
- following changes get commited with the UIDs: 1, 2, 3 and 4
- in sync_done the syncml peers send mapping changes for:
- 1 changes to 3
- 2 changes to 4
- 3 changes to 5
- 4 changes to 6
A simple SQL UPDATE would make the table inconsistent if the UPDATE would get called in a sequence. Maybe this could be workaround with a complex SQL statement - but this would only solve problems of a single <Map> update. Since those can appear delayed on the next sync, or the sync after the next sync a complex SQL couldn't solve the problem - right? Example:
Sync #1
- Commit of changes: 1, 2, 3 and 4
- sync_done
- map/uid updates:
- 1 changes to 2
- 2 changes to 3
- map/uid updates:
- sync finished
- disconnect
Sync #2
- commit: no changes to commit
- sync_done
- map/uid updates:
- 3 changes to 4 MALFORMED mapping table
- 4 changes to 5 MALFORMED mapping table
- map/uid updates:
On a regular SQL update this would cause that there would be multiple entries with the same/wrong UID.
Background
This should also solve an IPC deadlock issue with the SyncML which exceeds the IPC pending limit. The issue solved by replying to all the OSyncContext messages which get queued up the IPC.
Change History
comment:1 Changed 2 years ago by dgollub
- Severity changed from normal to critical
- Milestone set to OpenSync 0.40
comment:8 Changed 2 years ago by dgollub
(In [5941]) Return commit context immdetially.
Use osync_context_report_uid_update() in sink sync_done() phase to report UID changes. This is required since SyncML is working async and report mappings changes, with the <Map> command, once all changes got commmit. So we do this in sync_done()
Tested only DataSync?-Server plugin. DataSync?-Client untested.
TODO: How to handle commit errors without commit context in syncml-plugin?
refs #1161
