我正在将本地客户端与 DAV 文件夹(在这种特殊情况下为 CardDAV)同步。
对于这个文件夹,我有 ETag(SabreDAV 方言中的 CTag,用于区分文件夹 etag 和项目 etag)。如果 CTag 已更改,我需要再次重新同步。但是如果这个变化是我自己造成的(例如我刚刚上传了一个联系人到这个 CardDAV 文件夹中),有没有办法避免重新同步?
理想情况下,我希望 DAV 服务器会在每个请求上返回此信息,这会更改服务器上的任何内容:
- CTag1,当前文件夹的 CTag,与应用我的操作之前一样
- CTag2,应用我的操作后当前文件夹的 CTag
- 分配给相关项目的 ETag(尽管它与此特定问题无关)。
这将使我了解 CTag 更改是否仅由我自己的操作(并且不需要重新同步)或两者之间发生的其他事情引起(因此需要重新同步)。
目前,我只能随时查询文件夹的 CTag,但我不知道如果 CTag 发生更改该怎么办(在伪代码中):
cTag0 = ReadStoredValue() ' The value left from the previous sync.
cTag1 = GetCTag()
If cTag0 <> cTag1 Then
Resync()
End If
UploadItem() ' Can get race condition if another client changes anything right now
cTag2 = GetCTag()
cTag2 显然与 cTag1 不同,但这提供了关于中间是否发生其他事情的零信息(另一个客户端更改了同一文件夹中的某些内容)。所以,cTag0 <> cTag1 compare 不会让我免于竞争条件,我可以认为我是同步的,而其他一些更新偷偷地被忽视了。
拥有会很棒:
cTag0 = ReadStoredValue() ' The value left from the previous sync.
(cTag1, cTag2) = UploadItem()
If cTag0 == cTag1
' No resync needed, just remember new CTag for the next sync cycle.
cTag0 = cTag2
Else
Resync()
cTag0 = cTag2
End If
我知道 DAV-Sync 协议扩展,但这将是另一回事。在这个任务中,我指的是标准 DAV,不允许扩展。
编辑:我脑海中闪过一个念头。我注意到 CTag 是连续的。这是一个在对文件夹的每次操作中都会增加 1 的数字。因此,如果在获得 CTag、执行我的操作和再次获得 CTag 之间增加了 1 以上,这将表明刚刚发生了其他事情。但这似乎并不可靠,恐怕它过于特定于实现而无法依赖这种行为。寻找更强大的解决方案。