Ticket #1161 (closed task: fixed)

Opened 2 years ago

Last modified 2 years ago

[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

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
  • 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

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:2 Changed 2 years ago by tuju

  • Cc tuju added

comment:3 Changed 2 years ago by dgollub

(In [5925]) Introduce internal hashtable function to update the UID. This got introduced for osync_context_report_uid_update()

see #1161

comment:4 Changed 2 years ago by dgollub

(In [5926]) Introduce archive function to update the UID in the mapping-table, which is inside the archive-database.

see #1161

comment:5 Changed 2 years ago by dgollub

(In [5927]) Update hashtable if a plugin sends a osync_context_report_uid_update() event.

see #1161

comment:6 Changed 2 years ago by dgollub

(In [5928]) Implement the required mapping-table update calls for a UID-update during the sync-done phase.

osync_context_report_uid_update() is no longer NOP.

see #1161

comment:7 Changed 2 years ago by dgollub

  • Status changed from new to closed
  • Resolution set to fixed

(In [5929]) Introduced context-unittest

Currently only the osync_context_report_uid_update() function gets tested.

Fixes #1161

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

Note: See TracTickets for help on using tickets.