Skip to content

Commit

Permalink
Merge pull request #108 from Kinto/clarify-docs-for-incoming-conflicts
Browse files Browse the repository at this point in the history
Clarify docs about having to resolve incoming conflicts
  • Loading branch information
Natim committed Sep 7, 2015
2 parents 088cf0d + a87457b commit 56a018e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 24 deletions.
66 changes: 43 additions & 23 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ Synopsis:
- The developer has to handle them manually using [`#resolve()`](#resolving-conflicts), and call `#sync()` again when done;
3. If everything went fine, publish local changes;
- Fail on any publication conflict detected;
* If `strategy` is set to `Collection.strategy.SERVER_WINS`, no remote data override will be performed by the server;
* If `strategy` is set to `Collection.strategy.CLIENT_WINS`, conflicting server records will be overriden with local changes;
* If `strategy` is set to `Collection.strategy.MANUAL`, conflicts will be reported in a dedicated array.
* If `strategy` is set to `Collection.strategy.SERVER_WINS`, no client data will overwrite the remote data;
* If `strategy` is set to `Collection.strategy.CLIENT_WINS`, conflicting server records will be overwritten with local changes;
* If `strategy` is set to `Collection.strategy.MANUAL`, both incoming and outgoing conflicts will be reported in a dedicated array.

```js
articles.sync()
Expand All @@ -261,39 +261,53 @@ If anything goes wrong during sync, `colllection.sync()` will reject its promise

### Synchronization strategies

The `sync()` method accepts a `strategy` option, which itself accepts the following values:
For publication conflicts, the `sync()` method accepts a `strategy` option, which itself accepts the following values:

- `Collection.strategy.MANUAL` (default): Conflicts are reflected in a `conflicts` array as a result, and need to be resolved manually.
- `Collection.strategy.MANUAL` (default): Conflicts are reflected in a `conflicts` array as a result, and need to be resolved manually;
- `Collection.strategy.SERVER_WINS`: Server data will be preserved;
- `Collection.strategy.CLIENT_WINS`: Client data will be preserved.

> Note:
> `strategy` only applies to *outgoing* conflicts. *Incoming* conflicts will still
> be reported in the `conflicts` array. See [`resolving conflicts section`](#resolving-conflicts).

You can override default options by passing `#sync()` a new `options` object; Kinto will merge these new values with the default ones:

```js
import Collection from "kinto/lib/collection";

articles.sync({
strategy: Collection.strategy.CLIENT_WINS,
headers: {Authorization: "Basic bWF0Og=="}
})
.then(console.log.bind(console));
.catch(console.error.bind(console));
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
});
```

The synchronization updates the local data, and provides information about performed operations.
Sample result:

```js
{
ok: true,
lastModified: 1434270764485,
conflicts: [], // Outgoing and incoming conflicts
errors: [], // Errors encountered, if any
created: [], // Created locally
updated: [], // Updated locally
deleted: [], // Deleted locally
conflicts: [], // Import conflicts
skipped: [], // Skipped imports
published: [] // Successfully published
}
```

## Resolving conflicts

If conflicts occured, they're listed in the `conflicts` property; they must be resolved locally and `sync()` called again.

The `conflicts` array is in this form:
Expand All @@ -303,7 +317,7 @@ The `conflicts` array is in this form:
//
conflicts: [
{
type: "incoming", // can also be "outgoing"
type: "incoming", // can also be "outgoing" if stategy is MANUAL
local: {
_status: "created",
id: "233a018a-fd2b-4d39-ba85-8bf3e13d73ec",
Expand All @@ -318,24 +332,30 @@ The `conflicts` array is in this form:
}
```

## Resolving conflicts

Conflict resolution is achieved using the `#resolve()` method:
Once the developer is done with merging records, conflicts are marked as
resolved using the `#resolve()` method of the collection:

```js
articles.sync()
.then(res => {
if (!conflicts.length)
return res;
return Promise.all(conflicts.map(conflict => {
return articles.resolve(conflict, conflict.remote);
}));
})
.then(_ => articles.sync())
.catch(console.error.bind(console));
function sync() {
return articles.sync()
.then(res => {
if (res.ok)
return res;

// If conflicts, take remote version and sync again.
return Promise.all(res.conflicts.map(conflict => {
return articles.resolve(conflict, conflict.remote);
}))
.then(_ => sync());
})
.catch(error => {
console.error(error);
});
}
```

Here we're solving encountered conflicts by picking all remote versions. After conflicts being properly addressed, we're syncing the collection again.
Here we're solving encountered conflicts by picking all remote versions. After conflicts being properly addressed, we're syncing the collection again, until no conflicts occur.


## Handling server backoff

Expand Down
2 changes: 1 addition & 1 deletion docs/limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Kinto.js doesn't track modification history in a form of a revision tree. Instead, it provides information about what eventually changed since the last time you asked, and only that.

This allows covering 80% of common synchronization use cases, while being super-lightweight implementation wise.
This allows covering most synchronization use cases, while being super-lightweight implementation wise.

You can read more about Kinto features [here](http://kinto.readthedocs.org).

Expand Down

0 comments on commit 56a018e

Please sign in to comment.