多端登录同步策略

字段表示

1
2
3
4
5
6
7
8
9
本地列表:local_list;
单项:local
本地修改时间: localTime
上次快照时间: snapTime

远程列表:remote_list;
单项:remote
上次同步时间: syncTime

状态判断

  1. 本地删除的(还没提交到远程,就删除的,针对这种情况可以直接清理掉)

    (local.snapTime == 0L && local.isDisabled)

  2. 无变化的

    (local.localTime == local.snapTime) && (local.snapTime == remote.syncTime)

  3. 本地新增的

    ((local.snapTime == 0L) && (local.localTime > 0))

  4. 远程新增的

    (remote_list.subtract(local_list))

  5. 本地修改的

    ((local.snapTime == remote.syncTime) && (local.localTime > local.snapTime))

  6. 远程修改的

    ((local.localTime == local.snapTime) && (remote.syncTime > local.snapTime))

  7. 远程和本地都有修改的

    (local.localTime > local.snapTime) && (remote.syncTime > local.snapTime)

冲突解决

对于前 6 个状态,是不需要处理冲突的, 简单的合并处理即可。

对于第 7 个,是需要手动来解决的。

上传同步

  1. 取当前时间:
1
val now = Date().time
  1. 设置修改时间:
1
2
sync_list.map { it.syncTime=now }
local_list.map { it.localTime=now; it.snapTime=now }
  1. 上传 sync_list 到服务器

参考:

从客户端的角度来看,文件同步的本质是本地文件集合与云端文件集合的对比。从实现角度来讲,客户端会保存一份云端文件集合的快照,通过将快照和云端集合对比可以计算出云端文件变更,通过将快照和本地集合对比则可以计算出本地文件变更。对于本地文件的变更,需要将文件提交至云端;对于云端文件的变更,需要将文件同步至本地。对于文件同步在云端和本地都有修改的情况下,就需要进行冲突处理。

为减少内存占用,不采取云端快照到本地的方式;这里换了种方式:在本地数据库中只加了个 snapTime 快照时间 ,来作为参考点;

更多思考

  • 在处理冲突期间,远程数据库已经被另一端上传覆盖了。
  • 本地的修改时间比快照时间还小?