FeedSync for Atom and RSS

Version: 1.0.2
Contact: Jack Ozzie, George Moromisato, Matt Augustine, Paresh Suthar and Steven Lees, Microsoft Corporation
Updated: June 1, 2010

1    Overview

The scope of FeedSync for Atom and RSS is to define the minimum extensions necessary to enable loosely-cooperating applications to use Atom and RSS feeds as the basis for item sharing – that is, the bi-directional, asynchronous synchronization of new and changed items amongst two or more cross-subscribed feeds.

This specification extends the following specifications:

One of the guiding principles of FeedSync is to reinvent as little as possible—hence the use of Atom and RSS in this spec as the underlying format for exchanging FeedSync data. It is expected that there will be additional container format bindings for FeedSync in the future.

1.1   Namespaces and Version

The XML namespace URI for the XML data format described in this specification is:

  • http://feedsync.org/2007/feedsync

In this spec, the prefix "sx:" is used for the namespace URI identified above.

Atom example:

<feed xmlns="http://www.w3.org/2005/Atom"
  xmlns:sx="http://feedsync.org/2007/feedsync">

RSS example:

<rss version=”2.0”
  xmlns:sx="http://feedsync.org/2007/feedsync">

1.2   Notational Conventions

  1. In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in RFC 2119.
  2. The term item denotes a typed data entity and the basic unit of sharing and synchronization.
  3. The term endpoint denotes an entity that participates in the synchronization of shared items with other endpoints.  An endpoint can act as a publisher, a subscriber or both. The entity represented by an endpoint could be a user or group, or something more precise such as a specific user on a specific device.
  4. An endpoint's item set is a complete set of related items as determined by the endpoint.
  5. A feed is an addressable collection of items in an endpoint's item set represented in the Atom 1.0 or RSS 2.0 format. The feed can be partial (only the items that have changed within a given time window) or complete (all of the items in the endpoint's item set are contained in the feed as of its publishing).
  6. A subscription is a unidirectional relationship between two endpoints where one endpoint acting as a subscriber pulls feeds from the other endpoint, which acts as a publisher.
  7. The term updated is used to include items created, changed or deleted.
  8. The term incorporate denotes the act of creating or updating a local feed item reflecting those updates made to the item in a remotely subscribed feed. 

1.3   Usage Model

Consider two loosely coupled endpoints, A and B, that wish to share and co-edit a set of independent items in an Atom feed. The two endpoints can use FeedSync to synchronize the set. The process would look like this:

  1. Endpoint A maintains an item set. Endpoint A publishes the set as a feed conforming to the FeedSync format. Let's call this feed-A.
  2. Endpoint B also maintains an item set. Endpoint B subscribes to feed-A and incorporates the items into its own set.
  3. Endpoint B publishes its own set (including items it got from A) as a feed conforming to the FeedSync format. Let's call this feed-B.
  4. Endpoint A subscribes to feed-B and incorporates items from endpoint B into its own set. In effect, endpoints A and B mutually publish/subscribe to each other's feeds.
  5. When endpoint A adds or updates an item, that update is reflected in feed-A and endpoint B receives the change when it reads the feed.
  6. Similarly, when endpoint B adds or updates an item, the update is published in feed-B and endpoint A receives the change.

The extensions described in the FeedSync specification enable feed readers and publishers to generate and process incoming item changes in a manner that enables consistency to be achieved.  In order to accomplish this, FeedSync introduces concepts such as per-item change history (to manage item versions and update conflicts) and tombstones (to propagate deletions, and un-deletions).

Note that FeedSync is useful for one-way synchronization as well. For example, Endpoint A might only publish items through feed-A, but not accept updates. Endpoint B can use FeedSync as an efficient way to track published changes from Endpoint A.

1.4   Example Feeds

These feeds demonstrate a series of updates to single item.

1.4.1   Atom Feed

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:sx="http://feedsync.org/2007/feedsync">
  <title>To Do List</title>
  <subtitle>A list of items to do</subtitle>
  <link rel="self" href="http://example.com/partial.xml"/>
  <author>
    <name>Ray Ozzie</name>
  </author>
  <updated>2005-05-21T11:43:33Z</updated>
  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aaa</id>
  <sx:sharing since="2005-02-13T18:30:02Z"
    until="2005-05-23T18:30:02Z" >
   <sx:related link="http://example.com/all.xml" type="complete" />
   <sx:related link="http://example.com/B.xml" type="aggregated"
    title="To Do List (Jacks Copy)" />
  </sx:sharing>
  <entry>
   <title>Buy groceries</title>
   <content>Get milk, eggs, butter and bread</content>
   <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aa0</id>
   <author>
    <name>Ray Ozzie</name>
   </author>
   <updated>2005-05-21T11:43:33Z</updated>
   <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="3">
    <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
    <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
    <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
   </sx:sync>
  </entry>
</feed>

1.4.2   RSS Feed

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sx="http://feedsync.org/2007/feedsync">
 <channel>
  <title>To Do List</title>
  <description>A list of items to do</description>
  <link> http://example.com/partial.xml </link>
  <sx:sharing since="2005-02-13T18:30:02Z"
    until="2005-05-23T18:30:02Z" >
   <sx:related link="http://example.com/all.xml" type="complete" />
   <sx:related link="http://example.com/B.xml" type="aggregated" 
    title="To Do List (Jacks Copy)" />
  </sx:sharing>
  <item>
   <title>Buy groceries</title>
   <description>Get milk, eggs, butter and bread</description>
   <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="3">
    <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
    <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
    <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
   </sx:sync>
  </item>
 </channel>
</rss>

2    Extensions

2.1 Common requirements

The following requirements apply to all parts of this specification.

  1. All endpoint identifiers MUST conform to the syntax for Namespace Specific Strings (the NSS portion of a URN) in RFC 2141. Endpoint identifiers MUST be chosen so that they always uniquely identify an endpoint, even when additional endpoints are added to the mesh over time. See the definition of the by attribute in section 2.5 for more information on endpoint identifiers.
  2. Unless otherwise specified, if an xml element attribute value is set, it MUST be set to a non-empty string value.
  3. Unless otherwise specified, string attributes are unbounded.  An implementation MAY prevent incorporation of an item if one or more string attributes exceed bounds imposed by that implementation.
  4. Unless otherwise specified, the comparison of string attributes MUST be done using the Unicode code point values of each character, and this comparison MUST be culture insensitive. A string starting with Unicode code point X sorts before a string starting with Unicode code point Y, if X is less than Y. This collation is not for presentation purposes, and is intentionally not the same as the algorithm described by the “Unicode Collation Algorithm” (http://www.unicode.org/reports/tr10/).
  5. All date-time values MUST conform to the Date and Time specification of RFC 3339, with the following added constraints:
    • Times MUST be expressed in whole seconds only; fractional second values MUST NOT be present.
    • Times MUST be given in the UTC timezone, and end in “Z”, without a timezone offset.
  6. It is strongly RECOMMENDED that all attributes that contain human readable strings contain plain text only. This includes the title attribute on sx:related and the by attribute on sx:history, and any other such attributes in this specification whose contents are intended to be human readable. It is NOT RECOMMENDED to include any embedded HTML or XML in those elements, and any such inclusion is ignored by this spec.
  7. A feed may contain XML markup which is not defined either by this specification or by the feed format (RSS or Atom) specification. (This is similar to the notion of “foreign markup” in section 6.1 of the Atom specification.) This markup might include application extensions to FeedSync, or might include future extensions to FeedSync. Any such markup SHOULD be preserved and republished by an FeedSync endpoint.

2.2   <sx:sharing> element within Atom <feed> or RSS <channel>

The sx:sharing element is optional. If it exists, the sx:sharing element MAY contain one or more sx:related elements. Note that since a feed is not required to contain sx:sync elements, a feed containing only the sx:sharing element but no sx:sync elements is a valid FeedSync feed.

The sx:sharing element and all elements contained inside it are intended to be publisher-specific. That is, sx:sharing is used to communicate information from a feed publisher to the specific feed consumer that requested the feed. Endpoints that consume the feed MUST NOT republish the sx:sharing element or any of its sub-elements to other feed consumers.

Attributes Description
since An optional, string attribute. If present, its value is set by the publisher as a lower bound of items contained within the feed.  See section 4 for more information.

Note:  If this attribute is exists, the until attribute MUST also exist.
until An optional, string attribute. If present, its value is set by the publisher as an upper bound of items contained within the feed.  See section 4 for more information.

Note:  If this attribute is exists, the since attribute MUST also exist.
expires An optional, date-time attribute. If present, represents a publisher suggested date-time before which subscribers SHOULD read the feed in order to avoid missing item updates.  See section 4 for more information.

The value for this attribute SHOULD be interpreted as a best effort, uncalibrated value.

2.3   <sx:related> element within <sx:sharing>

The sx:related element is optional, but when present contains information about related feeds or locations.

Attributes Description
link A required, URI attribute. The URI for the related feed. This attribute MUST be an absolute-URI as defined in RFC3986. It MUST NOT be a relative reference.
title An optional, string attribute. If present, represents the name or description of the related feed.
type A required, string attribute. This attribute can have one of the following values:

"complete" if the link points to a feed that contains the complete collection of items for this feed. See section 4 for more information.

"aggregated" if the link points to a feed whose contents are being incorporated into this feed by the publisher.

2.3.1   Aggregated Feeds

In the case where a publisher’s feed has incorporated items from other feeds, it can be useful for subscribers to see more detailed information about the other feeds.  In the case of feed sharing as envisioned by this specification, this feature can also be used to notify subscribing feeds of the feeds of other participants which they might also wish to subscribe to.

Atom Example

<feed>
  <sx:sharing>
   <sx:related link="http://example.com/all.xml" type="complete" />
   <sx:related link="http://example.com/B.xml" type="aggregated" 
    title="To Do List (Jacks Copy)" />
  </sx:sharing>
       ...
</feed>

RSS Example

<channel>
 <sx:sharing>
   <sx:related link="http://example.com/all.xml" type="complete" />
   <sx:related link="http://example.com/B.xml" type="aggregated" 
    title="To Do List (Jacks Copy)" />
 </sx:sharing>
       ...
</channel>

2.4   <sx:sync> element within feed item elements (e.g. <entry> in Atom or <item> in RSS)

The most important extension described in this specification is the sx:sync element, which contains the information required for synchronization. This element is a child of an element (e.g. <entry> or <item>) that is a child of the feed or channel element. This is a REQUIRED element of all items in all feeds wishing to participate in FeedSync-based synchronization. Note that since the sx:sharing element is not required, feed consumers MUST consider the presence of sx:sync elements in items or entries as an indication that the feed contains sync data.

Note: is it acceptable for a feed to have some items or entries with sx:sync elements, and some without sx:sync. Only the items and entries that include the sx:sync element participate in FeedSync synchronization.

Attributes Description
id A required, string attribute. This is the identifier for the item. The ID MUST be globally unique within the feed and it MUST be identical across feeds if an item is being shared or synchronized as part of multiple distinct independent feeds.

Note: Atom has a similar requirement for each entry to have a unique id. While the Atom entry id could be used for the sync id at the publisher’s discretion, implementers MUST NOT assume that the Atom id for the entry matches the sync id. Likewise, if the RSS item includes a GUID, implementers MUST NOT assume that the GUID is the same as the sync id.

Note:  The ID is assigned by the creator of the item, and MUST NOT be changed by subsequent publishers. Applications will collate and compare these identifiers; therefore they MUST conform to the syntax for Namespace Specific Strings (the NSS portion of a URN) in RFC 2141.
updates A required, integer attribute.  This is number of updates applied to an item, where valid values are from 1 to 2^31-1.

Note:  The attribute’s value starts at 1 for new items.
deleted An optional, boolean attribute. If present and its value is "true" (lower-case), it indicates that the item has been deleted and this is a tombstone.  If not present, or if present with value of "false", then the item is not deleted.  All other values are invalid.
noconflicts An optional, boolean attribute. If present and its value is "true" (lower-case), it indicates that conflict preservation MUST NOT be performed.  If not present, or present with a value of "false", then it indicates that conflict preservation MUST be performed for the item.  All other values are invalid.

Note:  This value MUST only be set once, and SHALL only be set when the updates attribute value is 1. All updates to the item after the first update must propagate whatever attribute state was set on the first update (true, false, or not present).

2.5   <sx:history> element within <sx:sync>

The sx:sync element MUST contain at least one sx:history sub-element.  These sub-elements represent information about updates to the item, with the most recent update being first/topmost.

Attributes Description
sequence A required, integer attribute. This is the sequencing of individual updates for the purposes of conflict detection, where valid values are from 1 to 2^31-1.

The sequence number is typically assigned by copying the updates attribute value on sx:sync, after it has been incremented at the time of an update. See sections 3.1 and 3.2 for details.
when An optional, date-time attribute. If present, represents the date-time for the device that performed the item modification.

The value for this attribute SHOULD be interpreted as a best effort, uncalibrated value.

Note: Either or both of the when or by attributes MUST be present; it is invalid to have neither. It is RECOMMENDED that implementers include both when and by attributes whenever possible.
by An optional, string attribute. If present, represents the text value that uniquely identifies the endpoint that made the modification.

Note: Either or both of the when or by attributes MUST be present; it is invalid to have neither. It is RECOMMENDED that implementers include both when and by attributes whenever possible.

Note: Implementations should not assume that the by attribute will be a human-readable indication of the author of the item; it is simply intended as a unique identifier for use in the sync algorithm. As mentioned in section 1.2.3, the precise entity represented by an endpoint will vary depending on the application.

2.6   <sx:conflicts> element within <sx:sync>

The sx:sync element might contain an sx:conflicts sub-element.  When the sx:conflicts element is present and contains one or more item or entry sub-elements, each item or entry represents a conflicting update.  An empty sx:conflicts element in an item or entry MUST be considered equivalent to not having any sx:conflicts element in that item or entry, and indicates that there are no conflicts present. See conflict preservation behavior (section 3.4) for more information.

Attributes Description
N/A N/A

3    Required Behaviors for Global Consistency

To assure consistency when modifying a local feed, the following behaviors will be defined:

  • Creation
  • Update/Deletion
  • Conflict Resolution


To assure consistency when processing incoming (subscribed) feeds, the following behaviors will be defined:

  • Merge

3.1   Creation Behavior

When creating a new item as the result of a local operation, implementations MUST:

  1. Create a sx:sync element as follows:
    1.  Set the id attribute (in conformance with section 2.3)
    2.  Set the updates attribute to 1
    3.  Optionally set the noconflicts attribute
    4.  Optionally set the deleted attribute if the item is tombstoned from birth
  2. Create a sx:history element as follows:
    1.  Set the sequence attribute (in conformance with section 2.5). It is RECOMMENDED that the sequence value be set to 1.
    2.  Do one or both of the following:
      1.  Set the when attribute to the current date-time.  Note that this attribute is optional if the by attribute is set, but it is RECOMMENDED that this attribute be set whenever possible.
      2. Set the by attribute to the current endpoint's identifier.  Note that this attribute is optional if the when attribute is set, but it is RECOMMENDED that this attribute be set whenever possible.
    3.  Add the sx:history element as the topmost sub-element of the sx:sync element.
  3. Add the sx:sync element as a sub-element of the item’s element
  4. Append the item’s element as a sub-element of the feed element.
  5. Optionally update the until attribute for the sx:sharing element

Here is what an item could look like after being created:

Atom Example

<entry>
<title>Buy groceries</title>
<content>Get milk and eggs</content>
<updated>2005-05-21T09:43:33Z </updated>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aa0</id>
<author>
   <name>Ray Ozzie</name>
</author>
<sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="1">
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
</sx:sync>
</entry>

RSS Example

<item>
<title>Buy groceries</title>
<description>Get milk and eggs</description>
<sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="1">
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
</sx:sync>
</item>

3.2   Update/Deletion Behavior

When updating or deleting an item via a local operation, implementations MUST:

  1. Update the sx:sync element as follows:
    1. Increment the updates attribute by 1
  2. Create a sx:history element as follows:
    1. Do one or both of the following:
      1. Set the when attribute to the current date-time.  Note that this attribute is optional if the by attribute is set, but it is RECOMMENDED that this attribute be set whenever possible.
      2. Set the by attribute to the current endpoint's identifier.  Note that this attribute is optional if the when attribute is set, but it is RECOMMENDED that this attribute be set whenever possible.
    2. If the by attribute has not been set in Step 2a, set S1 to be the same value as the updates attribute set in Step 1.
    3. If the by attribute has been set in Step 2a:
      1. Set S1 to any valid value. It is RECOMMENDED that implementations set S1 to the same value as the updates attribute set in Step 1.
      2. Set S2 to be the greatest sequence value of all sx:history sub-elements of the sx:sync element with the same by attribute value as the value set in Step 2a.  Implementations MAY set S2 to be the greatest sequence value of all sx:history sub-elements across all items in the feed with the same by attribute value.
      3. If S1 <= S2, then set S1 to any valid value that is greater than S2. It is RECOMMENDED that implementations set S1 to (S2 + 1).
    4. Set the sequence attribute to S1.
  3. Add the sx:history element as the topmost sub-element of the sx:sync element.
  4. If the by attribute has been set in step 2a, and the sx:conflicts element is present and non-empty:
    1. For each item sub-element X of the sx:conflicts element:
      1. Set H to be the topmost sx:history sub-element of the sx:sync element for X
      2. If the by attribute of H is set and has the same value as the by attribute set in step 2a, then follow the steps for Merging Conflict Items (see Section 3.4) for item X
  5. If this is a deletion, set the deleted attribute on the sx:sync element to true.
  6. If this is an un-deletion, set the deleted attribute on the sx:sync element to false.

Additionally implementations MAY:

  1. Clean up sx:history sub-elements with a by attribute value so that only the sx:history sub-element with the highest sequence attribute value for a given by is retained, and all other sx:history sub-elements with the same by attribute value are discarded.
  2. If this is a deletion, remove the item’s data as long as the item’s sx:sync and topmost sx:history sub-elements are preserved.  Note that truncation or removal of data might cause unexpected results if a subsequent conflict occurs for the item, or if the item is subsequently undeleted. Also note that publishers SHOULD rely on the since, until, and expires attributes (if present) of the sx:sharing element to determine when to stop publishing items.
  3. Update the until attribute for the sx:sharing element.

Here is what the same item in the above example would look like after having been updated in sequence by the same endpoint:

Atom Example#1

<entry>
<title>Buy groceries</title>
<content>Get milk, eggs and butter</content>
<updated>2005-05-21T10:43:33Z</updated>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aa0</id>
<author>
   <name>Ray Ozzie</name>
</author>
<sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="2">
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
</sx:sync>
</entry>

RSS Example#1

<item>
 <title>Buy groceries</title>
 <description>Get milk, eggs and butter</description>
 <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="2">
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
 </sx:sync>
</item>

Here is what the same item in the above example would look like after having been updated in sequence by another endpoint:

Atom Example #2

<entry>
 <title>Buy groceries</title>
 <content>Get milk, eggs, butter and bread</content>
 <updated>2005-05-21T11:43:33Z</updated>
 <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aa0</id>
 <author>
   <name>Ray Ozzie</name>
 </author>
 <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="3">
  <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
 </sx:sync>
</entry>

RSS Example #2

<item>
 <title>Buy groceries</title>
 <description>Get milk, eggs, butter and bread</description>
 <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="3">
  <sx:history sequence="3" when="2005-05-21T09:43:33Z" by="JEO2000"/>
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
 </sx:sync>
</item>

3.3   Merge Behavior

When a subscribing endpoint incorporates items from a publishing endpoint’s feed, these items must be merged with the existing local items. The act of merging items from an incoming feed detects new items, item updates and item conflicts and produces a merged result feed.  The merging of two items with the same id attribute value will result in a ‘winning’ item that might have conflict items.  In order to merge items, implementations MUST follow this algorithm for the two items:

  1. If no local item exists with the same id attribute value as the incoming item, add the incoming item to the merge result feed; we are done processing the incoming item.
  2. Create a collection L and populate it with the local item and the local item’s conflicts (if any exist) by using the following steps:
    1.  For each item sub-element of the sx:conflicts element for the local item:
      1. Add the item sub-element to L
    2.  If the local item has a sx:conflicts sub-element, remove it
    3.  Add the local item to L
  3. Create a collection I and populate it with the incoming item and the incoming item’s conflicts (if any exist) by using the following steps:
    1.  For each item sub-element of the sx:conflicts element for the incoming item:
      1. Add the item sub-element to I
    2.  If the incoming item has a sx:conflicts sub-element, remove it
    3.  Add the incoming item to I
  4. Create a collection M that will be used to contain items that will appear in the merged result feed
  5. Create a reference W for the current ‘winning’ item and set it to an unassigned value
  6. Using L as the outer collection and I as the inner collection, perform the following step
  7. For each item X in outer collection:
    1.  For each item Y in inner collection:
      1. Determine if X is subsumed1 by Y – if so then remove X from the outer collection; process the next item in the outer collection
    2.  Add X to M
    3.  If W has not been assigned a value, set W to X; process the next item in the outer collection
    4.  Determine if X should be declared as the new ‘winning’ item3 – if so set W to X.
  8. Using I as the outer collection and L as the inner collection, perform step 7 again
  9. Add W to the merge result feed
  10. If the noconflicts attribute is set to true, then we are done processing
  11. If M contains more than one item:
    1.  Create a sx:conflicts element and add it as a sub-element of the sx:sync element for W
    2. For each item Z in M:
      1. If Z equals W (i.e. they are the same item), then process the next item in M
      2. Add Z as a sub-element of the sx:conflicts element created in step 11a.

Note that sub-elements of a sx:conflicts element are always preserved as a flat, unordered list.

1 Item Subsumption

An item X is subsumed by an item Y when the topmost sx:history sub-element of X is subsumed2 by one of the sx:history sub-elements of Y, where X and Y are items with the same id attribute value.  In order to determine if X is subsumed by Y, implementations MUST perform the following:

  1. Set HX as the topmost sx:history sub-element of X
  2. For each sx:history sub-element HY of item Y:
    1.  Compare HX with HY to see if HX is subsumed2 by HY – if so then X is subsumed by Y
  3. If no determination has been made as to whether X is or is not subsumed by Y, then X is not subsumed by Y

2 History Subsumption

To determine if a sx:history element HX is subsumed by a sx:history element HY, implementations MUST perform the following comparisons, in order, for HX and HY:

  1. If a by attribute exists for HX:
    1.  If HY has the same by attribute value as HX, and HY has an equal or greater sequence attribute value than HX, then HX is subsumed by HY
  2. If no by attribute exists for HX:
    1.  If no by attribute exists for HY, and the when and sequence attribute values for HX respectively matches the when and sequence attribute values for HY, then HX is subsumed by HY
  3. If no determination has been made as to whether HX is or is not subsumed by HY, then HX is not subsumed by HY

3 Winner Picking

The ‘winning’ item between an item X and an item Y is the item with most recent update , where X and Y are items with the same id attribute value.  In order to determine the ‘winning’ item, implementations MUST perform the following comparisons, in order, for X and Y:

  1. If X has a greater updates attribute value for the sx:sync sub-element than Y’s, then X is the ‘winning’ item
  2. If X has the same updates attribute value for the sx:sync sub-element as Y:
    1.  If X has a when attribute for the topmost sx:history sub-element and Y does not, then X is the ‘winning’ item
    2.  If X has a when attribute value for the topmost sx:history sub-element and that is chronologically later than Y’s, then X is the ‘winning’ item
    3.  If X has the same when attribute for the topmost sx:history sub-element as Y:
      1. If X has a by attribute for the topmost sx:history sub-element and Y does not, then X is the ‘winning’ item
      2. If X has a by attribute value for the topmost sx:history sub-element that is collates greater (see Section 2.1.4 for collation rules) than Y’s, then X is the ‘winning’ item
  3. Y is the ‘winning’ item

Here is what the same item in the above example would look like after having been independently updated by two endpoints, causing a conflict:

Atom Example

<entry>
 <title>Buy groceries - DONE</title>
 <content>Get milk, eggs, butter and bread</content>
 <updated>2005-05-21T12:43:33Z</updated>
 <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aa0</id>
 <author>
   <name>Ray Ozzie</name>
 </author>
 <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="4">
  <sx:history sequence="4" when="2005-05-21T12:43:33Z" by="GPM7383"/>
  <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
  <sx:conflicts>
   <entry>
    <title>Buy groceries</title>
    <content>Get milk, eggs, butter and rolls</content>
    <updated>2005-05-21T12:43:33Z</updated>
    <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aa0</id>
    <author>
      <name>Ray Ozzie</name>
    </author>
    <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="4">
      <sx:history sequence="4" when="2005-05-21T12:43:33Z" by="JEO2000"/>
      <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
      <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
      <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
    </sx:sync>
   </entry>
  </sx:conflicts>
 </sx:sync>
</entry>

RSS Example

<item>
 <title>Buy groceries - DONE</title>
 <description>Get milk, eggs, butter and bread</description>
 <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="4">
  <sx:history sequence="4" when="2005-05-21T12:43:33Z" by="GPM7383"/>
  <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
  <sx:conflicts>
   <item>
    <title>Buy groceries</title>
    <description>Get milk, eggs, butter and rolls</description>
     <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="4">
      <sx:history sequence="4" when="2005-05-21T12:03:33Z" by="JEO2000"/>
      <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
      <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
      <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
    </sx:sync>
   </item>
  </sx:conflicts>
 </sx:sync>
</item>

3.4   Conflict Resolution Behavior

Applications can allow users to "resolve" conflicts for an item, where "resolve" means to perform an update to the item that takes the conflicting item data into account in some meaningful way.  For items that have multiple conflicts, implementations MAY selectively resolve conflicts, keeping some conflicts unresolved and intact for subsequent resolution.  When a particular conflict is resolved, it is removed from the list of the item’s conflicts and merged into the item’s history.  In order to resolve conflicts, the following MUST occur:

  1. The user is presented, within some user interface, with the ‘winning’3 item data along with the data for each of the conflicting versions of that same item (i.e. retrieved from the sx:conflicts sub-elements of the item).  The user will then select one of the following actions:
    1.  To keep the most recent data as the “resolved” state (i.e. confirming that the latest state is the desired state)
    2.  To select one of the conflicting version’s data as the “resolved” state
    3.  To combine or otherwise create new data as the “resolved” state (i.e. creating their own desired state)
  2. The appropriate “resolved” state MUST be used to perform an update operation (section Section 3.2) to the item
  3. The conflict items the user factored into their decision MUST then be merged4 into the item’s history so the user isn’t asked to resolve the same conflict more than once. 

Note that while the steps above focus on user based conflict resolution, it does not obviate the possibility of programmatic conflict resolution.  Programmatic conflict resolution would require that all endpoints execute the same conflict resolution logic for deterministic results.

4 Merging Conflict Items

In order to merge conflict items into the resolved item’s history, implementations MUST:

  1. Set Y as a reference the resolved item
  2. Set Sy as a reference to the sx:sync sub-element for Y
  3. For each item sub-element X of the sx:conflicts element that has been resolved:
    1.  Set SX as a reference to the sx:sync sub-element for X
    2.  Remove X from the sx:conflicts element.
    3.  For each sx:history sub-element HX of SX:
      1. For each sx:history sub-element Hy of SY:
        1. Compare HX with Hy to see if HX can be subsumed2 by HY – if not then add HX as a sub-element of SY, immediately after the topmost sx:history sub-element of SY.
  4. If the sx:conflicts element contains no sub-elements, the sx:conflicts element SHOULD be removed.

Additionally implementations MAY:

  1. Clean up sx:history sub-elements with a by attribute value so that only the sx:history sub-element with the highest sequence attribute value for a given by is retained, and all other sx:history sub-elements with the same by attribute value are discarded.

Here is what the same item in the above example would look like after conflict resolution has occurred, where one of the endpoint’s changes are picked as the resolved state::

Atom Example

<entry>
 <title>Buy groceries - DONE</title>
 <content>Get milk, eggs, butter and bread</content>
 <updated>2005-05-21T12:53:33Z</updated>
 <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0aa0</id>
 <author>
   <name>Ray Ozzie</name>
 </author>
 <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="5">
  <sx:history sequence="5" when="2005-05-21T12:53:33Z" by="GPM7383"/>
  <sx:history sequence="4" when="2005-05-21T12:03:33Z" by="JEO2000"/>
  <sx:history sequence="4" when="2005-05-21T12:43:33Z" by="GPM7383"/>
  <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
 </sx:sync>
</entry>

RSS Example

<item>
 <title>Buy groceries - DONE</title>
 <description>Get milk, eggs, butter and bread</description>
 <sx:sync id="item_1_myapp_2005-05-21T11:43:33Z" updates="5">
  <sx:history sequence="5" when="2005-05-21T12:53:33Z" by="GPM7383"/>
  <sx:history sequence="4" when="2005-05-21T12:03:33Z" by="JEO2000"/>
  <sx:history sequence="4" when="2005-05-21T12:43:33Z" by="GPM7383"/>
  <sx:history sequence="3" when="2005-05-21T11:43:33Z" by="JEO2000"/>
  <sx:history sequence="2" when="2005-05-21T10:43:33Z" by="REO1750"/>
  <sx:history sequence="1" when="2005-05-21T09:43:33Z" by="REO1750"/>
 </sx:sync>
</item>

4    Partial Feeds and Complete Feeds

Publishers will generally include, in a feed, only the most recent modifications, additions, and deletions within some reasonable time window.  These feeds are referred to herein as partial feeds, whereas feeds containing the complete set of items are referred to as complete feeds.

In the feed sharing context new subscribers, or existing subscribers failing to subscribe within the published feed window, will need to initially copy a complete set of items from a publisher before being in a position to process incremental updates.  As such, this specification provides for the ability for the latter feed to reference the complete feed.  By placing the link to this feed in the feed descriptor, only the partial feed URL need to be distributed to potential subscribers.

The guidelines below explain how publishers and subscribers MAY optionally use since and until attributes for the sx:sharing element to ensure that all item updates are synchronized, even if the publisher periodically purges items from its feed.  Note that these guidelines are only applicable when the subscriber maintains a local store for the feed’s items.

4.1  Subscriber guidelines

4.1.1   The following steps SHOULD be followed by the subscriber for initial feed consumption

  1. Read the contents of the published feed
  2. See if a sx:related sub-element exists for the sx:sharing element, with a type attribute value of ‘complete’ – then repeat step 1 above with the feed URL specified by the link attribute
  3. Perform a merge operation (see Section 3.3)
  4. If the subscribed feed contains the since and until attributes for the sx:sharing element:
    1. The subscriber SHOULD cache the value of the until attribute for the sx:sharing element for subsequent feed consumption

4.1.2   The following steps SHOULD be followed by the subscriber for subsequent feed consumption

  1. Read the contents of the published feed
  2. If the feed contains the since and until attributes for the sx:sharing element and the subscriber cached the value of the until attribute from a previous read, then determine if the subscriber is out of sync with the feed:
    1.  If the value of the since attribute for the sx:sharing element is greater than the cached value of the until attribute:
      1. If a sx:related sub-element exists for the sx:sharing element, with a type attribute value of ‘complete’ – if so then repeat step 1 above with the feed URL specified by the link attribute
      2. The subscriber is out of sync with feed, so all items that were not created, or most recently updated, by the subscribing endpoint should be discarded from the subscriber’s local store.
      3. Subsequent feed consumption is complete for the out of sync subscriber. Continue with the steps outlined for initial feed consumption in section 5.1.1
    2. The subscriber SHOULD cache the value of the until attribute for the sx:sharing element for subsequent feed consumption
  3. Perform a merge operation for the feed items in the local store and the feed (see Section 3.3)

4.2  Publisher guidelines

4.2.1   The following steps SHOULD be followed by the publisher when publishing a feed for the first time (for either a complete or partial feed)

  1. If items will ever be purged from the feed:
    1. Set the value1 of the since attribute of the sx:sharing element to correspond to the incorporation of least recently updated item in the feed.
    2. Set the value1 of the until attribute of the sx:sharing element to correspond to the incorporation of most recently updated item in the feed.
    3. Optionally set the value of the expires attribute for the sx:sharing element to a date-time value before which subscribers SHOULD read the feed in order to avoid missing item updates due to items being purged from feed. 

4.2.2   The following steps MAY be followed by the publisher when subsequently publishing a feed

1. If the expires attribute for the sx:sharing element exists, update its value to a date-time before which subscribers SHOULD read the feed in order to avoid missing item updates.

4.2.3   The following steps SHOULD be followed by the publisher when incorporating an item update into the feed

  1. Increment the value of the until attribute for the sx:sharing element by an appropriate amount
  2. Associate and store the new value of the until attribute with the item
  3. If the expires attribute for the sx:sharing element exists, optionally keep track of the date-time when incorporating the item’s changes.  This value MAY be used in relation to the expires attribute for the sx:sharing element by the publisher when determining which items to remove from a feed.

4.2.4   The following steps SHOULD be followed by the publisher when removing an item from a feed

  1. If the stored value associated with the item from (step 2 in section 4.2.3) is greater than the value for the since attribute for the sx:sharing element, set the value for the since attribute for the sx:sharing element to the stored value

1since and until values

These values SHOULD be thought of as ever-increasing values that are represented in a manner that allows string collation by subscribers to yield the appropriate results.  For example, if the publisher uses a date-time value to represent an incorporation timestamp for since and until, the value  MUST be normalized for string comparison (e.g. “2006-05-02T09:10:33Z” instead of “2 May 2006 09:10:33”). 

5    References

RFC 2119, "Key words for use in RFCs to Indicate Requirement Levels".
RFC 2141, "URN Syntax".
RFC 3339, "Date and Time on the Internet: Timestamps".
RFC 3986, "Uniform Resource Identifier (URI): Generic Syntax".
RFC 4287, "The Atom Syndication Format".

6    Licensing Information

Microsoft's copyrights in this specification are licensed under the Creative Commons Attribution-ShareAlike License (version 3.0). To view a copy of this license, please visit http://creativecommons.org/licenses/by-sa/3.0. There is a separate patent promise called the Microsoft Open Specification Promise available to parties interested in implementing software that conforms to the FeedSync specification. This patent promise is available at this location: http://www.microsoft.com/interop/osp/default.mspx.

©2007 Microsoft Corporation

Last edited Oct 19, 2010 at 6:52 PM by psuthar, version 1

Comments

No comments yet.