r5 - 08 Dec 2006 - 09:51:37 - MorgenSagenYou are here: OSAF >  Projects Web  >  DevelopmentHome > ServicesWorkingGroup > SharingProject > ChandlerEIMSyncAlgorithm

Chandler EIM-based Sync Algorithm

When a sync takes place, the client produces a set of (outgoing) EIM records representing local changes since the last sync, and requests a set of (incoming) change records from the server. The request includes a sync-token which the server uses to determine how far back in time to retrieve changes. The server responds with a set of EIM records representing all remote changes since that sync. The client checks for conflicts (overlapping outoing and incoming changes) and resolves them. All remaining incoming changes are applied locally, and all remaining outgoing changes are sent to the server.

Definitions:

  • Model: set of record types (and filters)
  • Translator: importers, exporters, deleters and any special code (translates between items and records)
  • Serializer: translates between records and sharing format (EIMML, et al)
  • Baseline: the last "external" state of a shared collection. It's a dictionary whose keys are item UUIDs, with values that are dictionaries mapping record key to record

"One-Time" Set up :

  • Record types are defined, describing fields, record keys, filters, and record type URIs
  • A Translator class is implemented, including import/export/delete callbacks for all applicable record types

Setting up a particular Share:

  • Instantiate a Share object with empty baseline, and None for last_repo_version and sync_token
  • Instantiate a Translator object
  • Interrogate the Translator for filtering options, to present to the user (alarms, status, triage)

Client-Server Sync Algorithm

# Generate records for all outbound items
for item in changed_items:
    rsNewBase[item.itsUUID] = Recordset(translator.exportItem(item))

for itemUUID, rs in inbound_diff.items():
    # inbound records are grouped into record sets by UUID so that we
    # only have to load in a subset of the old baseline

    # diff inbound records against the baseline to get the set of true diffs
    dInbound = rs - rsOldBase.setdefault(itemUUID, empty_rs)    # Cosmo 0.6

    # if an inbound UUID has also been locally modified, conflicts are possible
    if itemUUID in rsNewBase:
        # Check for conflicts and update outbound data to include inbound
        # changes
        dLocal = rsNewBase[itemUUID] - rsOldBase[itemUUID]
        dLost[itemUUID] = dLocal - dInbound
        # dLost[itemUUID] now contains whatever local changes were overwritten
        # by inbound changes to a particular item

        # update the outbound records for the item, incorporating inbound changes
        rsNewBase[itemUUID] += dInbound

    # filter the inbound records (the user may have elected to filter attributes
    # such as reminders and status), and apply inbound changes to repository
    translator.importRecords(sync_filter(dInbound))
    translator.deleteRecords(dInbound.deletions)

    # update the baseline to reflect new item state
    rsOldBase[itemUUID] += dInbound

# send outbound changes
for itemUUID, rs in rsNewBase.items():
    if itemUUID in rsOldBase:
        # this locally modified item has been published in the past, so filter
        # records using the sync_filter which uses "NoChange" in fields we
        # aren't sharing
        dOutbound = sync_filter(rs - rsOldBase[itemUUID])
    else:
        # this locally modified item has not been published in the past, so filter
        # records using the publish_filter which uses default values in fields we
        # aren't sharing
        dOutbound = publish_filter(rs)
        rsOldBase[itemUUID] = empty_rs

    # If the external code receiving these changes understands diffs, we could
    # just send dOutbound
    #send(dOutbound) # not in Comso 0.6

    # However, until Cosmo does understand diffs, we need to package up the
    # entire record set for the locally modified item
    rsOldBase[itemUUID] += dOutbound
    send(rsOldBase[itemUUID])

-- MorgenSagen - 16 Nov 2006

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r5 < r4 < r3 < r2 < r1 | More topic actions
 
Open Source Applications Foundation
Except where otherwise noted, this site and its content are licensed by OSAF under an Creative Commons License, Attribution Only 3.0.
See list of page contributors for attributions.