如何在我修改 DAV 文件夹时确定它是否具有并行更新



我正在将本地客户端与DAV文件夹同步(在这种特殊情况下为CardDAV)。

对于这个文件夹,我有 ETag(SabreDAV 方言中的 CTag,用于区分文件夹电子标签和项目电子标签)。如果 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 比较不会将我从竞争条件中拯救出来,我可以认为我是同步的,而其他一些更新却悄悄地被注意到了。

很高兴有:

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 以上,这将表明刚刚发生了其他事情。但这似乎并不可靠,恐怕依赖这种行为太特定于实现。寻找更强大的解决方案。

如何在修改 DAV 文件夹时确定它是否具有并行更新

这与 如何避免CalDAV的时间冲突或重叠?

从技术上讲,在纯DAV中,您不能保证能够做到这一点。尽管在现实世界中,大多数服务器会在响应用于创建/更新资源的 PUT 时返回ETag。这允许您协调对同一资源的并发更改。

还有针对 *DAV 协议的日历服务器批量更改请求 某些服务器支持它,并提供了一种更具体的方式来执行此操作。 由于它不是 RFC,我不建议依赖它。

所以你可能会做的是看跌期权。如果这返回了 ETag,那么您很好,可以通过同步集合(通过任何机制,PROPFIND:1、CTag 或同步报告)进行协调。如果没有,您可以选择通过其他方式进行协调(例如比较/散列内容),或者只是将更改视为并发编辑,我认为大多数实现都是这样做的。

如果你很幸运,服务器也可能在PUT中返回CTag/sync-token。但是AFAIK没有标准,服务器不需要这样做。

对于这个文件夹,我有ETag(SabreDAV方言中的CTag)

这是你的误解。CTag 与 ETag 绝对不同,它是它自己的东西记录在这里: 卡尔达夫·

我知道DAV-Sync协议扩展,但这将是一个不同的故事。在此任务中,我指的是标准DAV,不允许扩展。

CTag根本不是DAV标准,它是一个私有的Apple扩展(没有RFC)。

标准 HTTP/1.1 规范 ETag。它对应于资源表示形式,不适用于与此不同的 WebDAV 集合内容。WebDAV集合通常也有内容(可以通过GET等检索),ETag对应于此内容。

取代专有CTag扩展的官方标准实际上是DAV-Sync,又名RFC 6578。sync-token属性和标头将替换CTag标头。

因此,如果"不允许扩展"是您的用例,则需要在客户端进行资源比较。Pure WebDAV 不提供此功能。

我注意到 CTag 是顺序的

CTag 不是顺序的,它们是不透明的令牌。特定服务器可以使用序列,但这完全是任意的。(所有DAV代币也是如此,它们总是不透明的)

最新更新