89
Implementing data synchronization API for mobile apps

Implementing data sync apis for mibile apps @cloudconf

Embed Size (px)

Citation preview

Page 1: Implementing data sync apis for mibile apps @cloudconf

Implementing data synchronization API for

mobile apps

Page 2: Implementing data sync apis for mibile apps @cloudconf

Michele OrselliCTO@Ideato

micheleorselli / ideatosrl

_orso_

[email protected]

Page 3: Implementing data sync apis for mibile apps @cloudconf

Agenda

scenario design choices

implementation alternative approaches

Page 4: Implementing data sync apis for mibile apps @cloudconf
Page 5: Implementing data sync apis for mibile apps @cloudconf
Page 6: Implementing data sync apis for mibile apps @cloudconf

Dealing with conflicts

A1

A2

?

Page 7: Implementing data sync apis for mibile apps @cloudconf

Brownfield project

several mobile apps for tracking user generated data (calendar, notes, bio data)

iOS & Android

~10 K users steadily growing at 1.2 K/month

Scenario

Page 8: Implementing data sync apis for mibile apps @cloudconf

MongoDB

Legacy App based on Codeigniter

Existing RPC-wannabe-REST API for data sync

Scenario

Page 9: Implementing data sync apis for mibile apps @cloudconf

For every resource

get updates:

POST /m/:app/get/:user_id/:res/:updated_from

create/send updates:

POST /m/:app/update/:user_id/:res_id/:dev_id/:res

Scenario

Page 10: Implementing data sync apis for mibile apps @cloudconf

api

Page 11: Implementing data sync apis for mibile apps @cloudconf

~6 different resources, ~12 calls per sync

apps sync by polling every 30 sec

every call sync little data

Scenario

Page 12: Implementing data sync apis for mibile apps @cloudconf

Rebuild sync API for old apps + 2 incoming

Enable image synchronization

More efficient than previous API

Challenge

Page 13: Implementing data sync apis for mibile apps @cloudconf
Page 14: Implementing data sync apis for mibile apps @cloudconf

Existing Solutions

Tstamps, Vector clocks,

CRDTs

syncML, syncano

Azure Data sync

Algorithms Protocols/API

Platform

couchDB, riak

Storage

Page 15: Implementing data sync apis for mibile apps @cloudconf

Not Invented Here?

Don't Reinvent The Wheel,Unless You Plan on Learning More About Wheels

J. Atwood

Page 16: Implementing data sync apis for mibile apps @cloudconf

2 different mobile platforms

Several teams with different skill level

Changing storage wasn’t an option

Forcing a particular technology client side wasn’t an option

Architecture

Page 17: Implementing data sync apis for mibile apps @cloudconf

Architecture

c1

server

c2

c3

sync logicconflicts resolution

thin clients

Page 18: Implementing data sync apis for mibile apps @cloudconf

In the sync domain all resources are managed in the same way

Implementation

Page 19: Implementing data sync apis for mibile apps @cloudconf

For every app:

one endpoint for getting new data

one endpoint for pushing changes

one endpoint for uploading images

Implementation

Page 20: Implementing data sync apis for mibile apps @cloudconf

GET /apps/:app/users/:user_id/changes[?from=:from]

POST /apps/:app/users/:user_id/merge

POST /upload/:res_id/images

The new APIs

Page 21: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

Page 22: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

Col 1

Col 2

Col 3

Page 23: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

Col 1

Col 2

Col 3

Sync Service

Page 24: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

Col 1

Col 2

Col 3

Sync Service

Page 25: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

Col 1

Col 2

Col 3

Sync Service

Page 26: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

Col 1

Col 2

Col 3

Sync Service

Page 27: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

Col 1

Col 2

Col 3

Sync Service

Page 28: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation$app->get(“/apps/{mApp}/users/{userId}/merge”,

function ($mApp, $userId, $app, $request){$lastSync = $request->get('from', null);$data = $request->get(‘data’, false);$syncService = $app[‘syncService’];$syncService->merge($data, $lastSync, $userId);

$response = new JsonResponse($syncService->getResult()

);

return $response;}

Page 29: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation$app->get(“/apps/{mApp}/users/{userId}/merge”,

function ($mApp, $userId, $app, $request){$lastSync = $request->get('from', null);$data = $request->get(‘data’, false);$syncService = $app[‘syncService’];$syncService->merge($data, $lastSync, $userId);

$response = new JsonResponse($syncService->getResult()

);

return $response;}

Page 30: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation$app->get(“/apps/{mApp}/users/{userId}/merge”,

function ($mApp, $userId, $app, $request){$lastSync = $request->get('from', null);$data = $request->get(‘data’, false);$syncService = $app[‘syncService’];$syncService->merge($data, $lastSync, $userId);

$response = new JsonResponse($syncService->getResult()

);

return $response;}

Page 31: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation$app->get(“/apps/{mApp}/users/{userId}/merge”,

function ($mApp, $userId, $app, $request){$lastSync = $request->get('from', null);$data = $request->get(‘data’, false);$syncService = $app[‘syncService’];$syncService->merge($data, $lastSync, $userId);

$response = new JsonResponse($syncService->getResult()

);

return $response;}

Page 32: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation$app->get(“/apps/{mApp}/users/{userId}/merge”,

function ($mApp, $userId, $app, $request){$lastSync = $request->get('from', null);$data = $request->get(‘data’, false);$syncService = $app[‘syncService’];$syncService->merge($data, $lastSync, $userId);

$response = new JsonResponse($syncService->getResult()

);

return $response;}

Page 33: Implementing data sync apis for mibile apps @cloudconf

Silex Implementation

$app['mongodb'] = new MongoDb(…);

$app[‘changesRepo’] = new ChangesRepository( $app[‘mongodb’]);

$app[‘syncService’] ? new SyncService( $app[‘changesRepo’]);

Page 34: Implementing data sync apis for mibile apps @cloudconf

GET /apps/:app/users/:user_id/changes?from=:from

Get changes

timestamp?

Page 35: Implementing data sync apis for mibile apps @cloudconf

timestamp are inaccurate

server suggests the “from” parameter to be used in the next request

Server suggest the sync time

Page 36: Implementing data sync apis for mibile apps @cloudconf

Server suggest the sync time

c1 server

GET /changes

{ ‘next’ : 12345, ‘data’: […] }

Page 37: Implementing data sync apis for mibile apps @cloudconf

Server suggest the sync time

c1 server

GET /changes

{ ‘next’ : 12345, ‘data’: […] }

GET /changes?from=12345

{ ‘next’ : 45678, ‘data’: […] }

Page 38: Implementing data sync apis for mibile apps @cloudconf

data format {id: ‘1’, ’type’: ‘measure’, ‘_deleted’: true}{id: 2’, ‘type’: ‘note’}{id: ‘3’, ‘type’: ‘note’}

ps: soft delete all the things!

what to transfer

Page 39: Implementing data sync apis for mibile apps @cloudconf

How do we generate an unique id in a distributed system?

unique identifiers

Page 40: Implementing data sync apis for mibile apps @cloudconf

How do we generate an unique id in a distributed system?

UUID (RFC 4122): several implementations in PHP (https://github.com/ramsey/uuid)

unique identifiers

Page 41: Implementing data sync apis for mibile apps @cloudconf

How do we generate an unique id in a distributed system?

Local/Global Id: only the server generates GUIDsclients use local ids to manage their records

unique identifiers

Page 42: Implementing data sync apis for mibile apps @cloudconf

unique identifiers

c1 server

POST /merge{ ‘data’: [ {’lid’: ‘1’, …}, {‘lid’: ‘2’, …}] }

{ ‘data’: [ {‘guid’: ‘58f0bdd7-1400’, ’lid’: ‘1’, …}, {‘guid’: ‘6f9f3ec9-1400’, ‘lid’: ‘2’, …}] }

Page 43: Implementing data sync apis for mibile apps @cloudconf

mobile generated data are “temporary” until sync to server

server handles conflicts resolution

conflict resolution algorithm (plain data)

Page 44: Implementing data sync apis for mibile apps @cloudconf

conflict resolution:

domain indipendent: e.g. last-write wins

domain dipendent: use domain knowledge to resolve

conflict resolution algorithm (plain data)

Page 45: Implementing data sync apis for mibile apps @cloudconf

function sync($data) {

foreach ($data as $newRecord) {

$s = findByGuid($newRecord->getGuid());

if (!$s) {add($newRecord);send($newRecord);continue;

}

if ($newRecord->updated > $s->updated) {update($s, $newRecord);send($newRecord);continue;

}

updateRemote($newRecord, $s);}

conflict resolution algorithm (plain data)

Page 46: Implementing data sync apis for mibile apps @cloudconf

function sync($data) {

foreach ($data as $newRecord) {

$s = findByGuid($newRecord->getGuid());

if (!$s) {add($newRecord);send($newRecord);continue;

}

if ($newRecord->updated > $s->updated) {update($s, $newRecord);send($newRecord);continue;

}

updateRemote($newRecord, $s);}

conflict resolution algorithm (plain data)

Page 47: Implementing data sync apis for mibile apps @cloudconf

function sync($data) {

foreach ($data as $newRecord) {

$s = findByGuid($newRecord->getGuid());

if (!$s) {add($newRecord);send($newRecord);continue;

}

if ($newRecord->updated > $s->updated) {update($s, $newRecord);send($newRecord);continue;

}

updateRemote($newRecord, $s);}

conflict resolution algorithm (plain data)

no conflict

Page 48: Implementing data sync apis for mibile apps @cloudconf

function sync($data) {

foreach ($data as $newRecord) {

$s = findByGuid($newRecord->getGuid());

if (!$s) {add($newRecord);send($newRecord);continue;

}

if ($newRecord->updated > $s->updated) {update($s, $newRecord);send($newRecord);continue;

}

updateRemote($newRecord, $s);}

conflict resolution algorithm (plain data)

remote wins

Page 49: Implementing data sync apis for mibile apps @cloudconf

function sync($data) {

foreach ($data as $newRecord) {

$s = findByGuid($newRecord->getGuid());

if (!$s) {add($newRecord);send($newRecord);continue;

}

if ($newRecord->updated > $s->updated) {update($s, $newRecord);send($newRecord);continue;

}

updateRemote($newRecord, $s);}

conflict resolution algorithm (plain data)

server wins

Page 50: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (plain data)

c1

{ ‘lid’: ‘1’, ‘guid’: ‘af54d’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

server

{ ’guid’: ‘af54d’, ‘data’: ‘BBB’, ‘updated’ : ’20’ }

Page 51: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (plain data)

c1 server

{ ‘lid’: ‘1’, ‘guid’: ‘af54d’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘data’ : ‘hello!’, ‘updated’: ’15’ } POST /merge

{ ’guid’: ‘af54d’, ‘data’: ‘BBB’, ‘updated’ : ’20’ }

Page 52: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (plain data)

c1 server

{ ‘lid’: ‘1’, ‘guid’: ‘af54d’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘data’ : ‘hello!’, ‘updated’: ’15’ } POST /merge

{ ‘guid’: ‘e324f’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

{ ’guid’: ‘af54d’, ‘data’: ‘BBB’, ‘updated’ : ’20’ }

Page 53: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (plain data)

c1 server

{ ‘lid’: ‘1’, ‘guid’: ‘af54d’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘data’ : ‘hello!’, ‘updated’: ’15’ } POST /merge

{ ‘guid’: ‘e324f’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

{ ’guid’: ‘af54d’, ‘data’: ‘BBB’, ‘updated’ : ’20’ }

Page 54: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (plain data)

c1 server

{ ‘lid’: ‘1’, ‘guid’: ‘af54d’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘data’ : ‘hello!’, ‘updated’: ’15’ } POST /merge

{ ‘guid’: ‘e324f’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

{ ’guid’: ‘af54d’, ‘data’: ‘AAA’, ‘updated’ : ’100’ }

Page 55: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (plain data)

c1 server

{ ‘lid’: ‘1’, ‘guid’: ‘af54d’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ’guid’: ‘af54d’, ‘data’: ‘AAA’, ‘updated’ : ’100’ }

{ ‘lid’: ‘2’, ‘data’ : ‘hello!’, ‘updated’: ’15’ } POST /merge

{ ‘guid’: ‘e324f’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

{‘ok’ : { ’guid’: ‘af54d’ }}

{‘update’ : { lid: ‘2’, ’guid’: ‘e324f’ }}

Page 56: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (hierarchical data)

How to manage hierarchical data?

{‘lid’ : ‘123456’,‘type’ : ‘baby’, …

}

{‘lid’ : ‘123456’,‘type’ : ‘temperature’, ‘baby_id : ‘123456’

}

Page 57: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (hierarchical data)

How to manage hierarchical data?1) sync root record2) update ids3) sync child records

{‘lid’ : ‘123456’,‘type’ : ‘baby’, …

}

{‘lid’ : ‘123456’,‘type’ : ‘temperature’, ‘baby_id : ‘123456’

}

Page 58: Implementing data sync apis for mibile apps @cloudconf

function syncHierarchical($data) {

sortByHierarchy($data);

foreach ($data as $newRootRecord) {

$s = findByGuid($newRootRecord->getGuid());

if($newRecord->isRoot()) {

if (!$s) {add($newRootRecord);updateRecordIds($newRootRecord, $data);send($newRootRecord);continue;

}

conflict resolution algorithm (hierarchical data)

Page 59: Implementing data sync apis for mibile apps @cloudconf

function syncHierarchical($data) {

sortByHierarchy($data);

foreach ($data as $newRootRecord) {

$s = findByGuid($newRootRecord->getGuid());

if($newRecord->isRoot()) {

if (!$s) {add($newRootRecord);updateRecordIds($newRootRecord, $data);send($newRootRecord);continue;

}

conflict resolution algorithm (hierarchical data)

parent records first

Page 60: Implementing data sync apis for mibile apps @cloudconf

function syncHierarchical($data) {

sortByHierarchy($data);

foreach ($data as $newRootRecord) {

$s = findByGuid($newRootRecord->getGuid());

if($newRecord->isRoot()) {

if (!$s) {add($newRootRecord);updateRecordIds($newRootRecord, $data);send($newRootRecord);continue;

}

conflict resolution algorithm (hierarchical data)

Page 61: Implementing data sync apis for mibile apps @cloudconf

function syncHierarchical($data) {

sortByHierarchy($data);

foreach ($data as $newRootRecord) {

$s = findByGuid($newRootRecord->getGuid());

if($newRecord->isRoot()) {

if (!$s) {add($newRootRecord);updateRecordIds($newRootRecord, $data);send($newRootRecord);continue;

}

conflict resolution algorithm (hierarchical data)

no conflict

Page 62: Implementing data sync apis for mibile apps @cloudconf

if ($newRootRecord->updated > $s->updated) {update($s, $newRecord);updateRecordIds($newRootRecord, $data);send($newRootRecord);continue;

} else {updateRecordIds($s, $data);updateRemote($newRecord, $s);

}} else {

sync($data);}

}

conflict resolution algorithm (hierarchical data)

remote wins

Page 63: Implementing data sync apis for mibile apps @cloudconf

if ($newRootRecord->updated > $s->updated) {update($s, $newRecord);updateRecordIds($newRootRecord, $data);send($newRootRecord);continue;

} else {updateRecordIds($s, $data);updateRemote($newRecord, $s);

}} else {

sync($data);}

}

conflict resolution algorithm (hierarchical data)

server wins

Page 64: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (hierarchical data)

{ ‘lid’: ‘1’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘parent’: ‘1’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

c1 serverPOST /merge

Page 65: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (hierarchical data)

c1

{ ‘lid’: ‘1’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘parent’: ‘1’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

serverPOST /merge

{ ‘lid’: ‘1’, ‘guid’ : ‘32ead’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

Page 66: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (hierarchical data)

c1

{ ‘lid’: ‘1’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘parent’: ‘32ead’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

serverPOST /merge

{ ‘lid’: ‘1’, ‘guid’ : ‘32ead’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

Page 67: Implementing data sync apis for mibile apps @cloudconf

conflict resolution algorithm (hierarchical data)

c1

{ ‘lid’: ‘1’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘parent’: ‘32ead’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

serverPOST /merge

{ ‘lid’: ‘1’, ‘guid’ : ‘32ead’, ‘data’ : ‘AAA’ ‘updated’: ’100’ }

{ ‘lid’: ‘2’, ‘parent’: ‘32ead’, ‘data’ : ‘hello!’, ‘updated’: ’15’ }

{‘update’ : { ‘lid’: ‘1’, ’guid’: ‘af54d’ }}

{‘update’ : { lid: ‘2’, ’guid’: ‘e324f’ }}

Page 68: Implementing data sync apis for mibile apps @cloudconf

e.g. “only one temperature can be registered in a given day”

how to we enforce domain constraints on data?

enforcing domain constraints

Page 69: Implementing data sync apis for mibile apps @cloudconf

e.g. “only one temperature can be registered in a given day”

how to we enforce domain constraints on data?1) relax constraints

enforcing domain constraints

Page 70: Implementing data sync apis for mibile apps @cloudconf

e.g. “only one temperature can be registered in a given day”

how to we enforce domain constraints on data?1) relax constraints2) integrate constraints in sync algorithm

enforcing domain constraints

Page 71: Implementing data sync apis for mibile apps @cloudconf

from findByGuid to findSimilar

first lookup by GUID then by domain rules

“two measures are similar if are referred to the same date”

enforcing domain constraints

Page 72: Implementing data sync apis for mibile apps @cloudconf

enforcing domain constraints

c1 server

Page 73: Implementing data sync apis for mibile apps @cloudconf

enforcing domain constraints

c1 server

{ ’guid’: ‘af54d’, ‘when’: ‘20141005’ }

Page 74: Implementing data sync apis for mibile apps @cloudconf

enforcing domain constraints

c1 server

{ ‘lid’: ‘1’, ‘when’: ‘20141005’ }

{ ’guid’: ‘af54d’, ‘when’: ‘20141005’ }

Page 75: Implementing data sync apis for mibile apps @cloudconf

enforcing domain constraints

c1 server

{ ‘lid’: ‘1’, ‘when’: ‘20141005’ }

{ ’guid’: ‘af54d’, ‘when’: ‘20141005’ }

POST /merge

Page 76: Implementing data sync apis for mibile apps @cloudconf

enforcing domain constraints

c1 server

{ ‘lid’: ‘1’, ‘when’: ‘20141005’ }

{ ’guid’: ‘af54d’, ‘when’: ‘20141005’ }

POST /merge

Page 77: Implementing data sync apis for mibile apps @cloudconf

enforcing domain constraints

c1 server

{ ‘lid’: ‘1’, ‘when’: ‘20141005’ }

{ ’guid’: ‘af54d’, ‘when’: ‘20141005’ }

POST /merge

{ ’guid’: ‘af54d’, ‘when’: ‘20141005’ }

Page 78: Implementing data sync apis for mibile apps @cloudconf

Binary data uploaded via custom endpoint

Sync data remains small

Uploads can be resumed

dealing with binary data

Page 79: Implementing data sync apis for mibile apps @cloudconf

Two steps*1) data are synchronized2) related images are uploaded

* this means record without file for a given time

dealing with binary data

Page 80: Implementing data sync apis for mibile apps @cloudconf

dealing with binary data

c1 server

POST /merge

POST /upload/ac435-f8345/image

{ ‘lid’ : 1, ‘type’ : ‘baby’, ‘image’ : ‘myimage.jpg’ }

{ ‘lid’ : 1, ‘guid’ : ‘ac435-f8345’ }

Page 81: Implementing data sync apis for mibile apps @cloudconf

Implementing this stuff is tricky

Explore existing solution if you can

Understanding the domain is important

What we learned

Page 82: Implementing data sync apis for mibile apps @cloudconf

vector clocks

Page 83: Implementing data sync apis for mibile apps @cloudconf

Conflict-free Replicated Data Types (CRDTs)

Constraining the types of operations in order to:

- ensure convergence of changes to shared data by uncoordinated, concurrent actors

- eliminate network failure modes as a source of error

CRDT

Page 84: Implementing data sync apis for mibile apps @cloudconf

Gateways handles sync

Data flows through channels

- partition data set

- authorization

- limit the data

Use revision trees

Couchbase Mobile

Page 85: Implementing data sync apis for mibile apps @cloudconf

Distributed DBEventually/Strong Consistency

Data Types

Configurable conflict resolution- db level for built-in data types- application level for custom data

Riak

Page 86: Implementing data sync apis for mibile apps @cloudconf

See you in Verona!

jsDay 13th-14th of May

http://2015.jsday.it/

phpDay 15th-16th of May

http://2015.phpday.it/

Questions?

Page 87: Implementing data sync apis for mibile apps @cloudconf

http://www.objc.io/issue-10/sync-case-study.htmlhttp://www.objc.io/issue-10/data-synchronization.html

https://dev.evernote.com/media/pdf/edam-sync.pdfhttp://blog.helftone.com/clear-in-the-icloud/

http://strongloop.com/strongblog/node-js-replication-mobile-offline-sync-loopback/http://blog.denivip.ru/index.php/2014/04/data-syncing-in-core-data-based-ios-apps/?lang=en

http://inessential.com/2014/02/15/vesper_sync_diary_8_the_problem_of_unhttp://culturedcode.com/things/blog/2010/12/state-of-sync-part-1.htmlhttp://programmers.stackexchange.com/questions/206310/data-synchronization-in-mobile-apps-multiple-devices-multiple-users

http://bricklin.com/offline.htmhttp://blog.couchbase.com/why-mobile-sync

Links

Page 88: Implementing data sync apis for mibile apps @cloudconf

Vector Clockshttp://basho.com/why-vector-clocks-are-easy/http://www.datastax.com/dev/blog/why-cassandra-doesnt-need-vector-clockshttp://basho.com/why-vector-clocks-are-hard/http://blog.8thlight.com/rylan-dirksen/2013/10/04/synchronization-in-a-distributed-system.html

CRDTshttp://christophermeiklejohn.com/distributed/systems/2013/07/12/readings-in-distributed-systems.htmlhttp://www.infoq.com/presentations/problems-distributed-systemshttps://www.youtube.com/watch?v=qyVNG7fnubQ

Riak http://docs.basho.com/riak/latest/dev/using/conflict-resolution/

Couchbase Sync Gatewayhttp://docs.couchbase.com/sync-gateway/http://www.infoq.com/presentations/sync-mobile-data

APIhttp://developers.amiando.com/index.php/REST_API_DataSynchttps://login.syncano.com/docs/rest/index.html

Links

Page 89: Implementing data sync apis for mibile apps @cloudconf

phones https://www.flickr.com/photos/15216811@N06/14504964841wat http://uturncrossfit.com/wp-content/uploads/2014/04/wait-what.jpgdarth http://www.listal.com/viewimage/3825918hblueprint: http://upload.wikimedia.org/wikipedia/commons/5/5e/Joy_Oil_gas_station_blueprints.jpgbuilding: http://s0.geograph.org.uk/geophotos/02/42/74/2427436_96c4cd84.jpgbrownfield: http://s0.geograph.org.uk/geophotos/02/04/54/2045448_03a2fb36.jpgno connection: https://www.flickr.com/photos/77018488@N03/9004800239no internet con https://www.flickr.com/photos/roland/9681237793vector clocks: http://en.wikipedia.org/wiki/Vector_clockcrdts: http://www.infoq.com/presentations/problems-distributed-systems

Credits