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

How to determine if a DAV folder had parallel updates while I was modifying it

我正在将本地客户端与 DAV 文件夹(在本例中为 CardDAV)同步。

对于这个文件夹,我有 ETag(SabreDAV 方言中的 CTag,用于区分文件夹 etag 和项目 etag)。如果 CTag 发生变化,我需要再次重新同步。但是如果这个变化是我自己造成的(比如我刚刚上传了一个联系人到这个CardDAV文件夹),难道没有办法避免重新同步吗?

理想情况下,我希望 DAV 服务器 return 每次请求都会更改此信息,这会更改服务器上的任何内容:

如果 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 中,您不能保证能够做到这一点。尽管在现实世界中,大多数服务器会 return 在对用于 create/update 资源的 PUT 的响应中 ETag。这允许您协调对同一资源的并发更改。

还有Calendar Server Bulk Change Requests for *DAV Protocols 某些服务器支持它,并提供更具体的方法来执行此操作。 由于它不是 RFC,因此我不建议依赖它。

所以您可能会做的是 PUT。如果那个 return 是你的 ETag,那么你很好,可以通过同步 collection(通过任何机制,PROPFIND:1、CTag 或 sync-report)来协调。如果 不是 ,您可以选择通过其他方式(例如 comparing/hashing 内容)进行协调,或者将更改视为并发编辑,我认为大多数实现做。

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

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

这是你的误解。 CTag 与 ETag 完全不同,它在此处记录了它自己的东西: CalDAV CTag.

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

CTag 根本不是 DAV 标准,它是 private Apple extension(没有 RFC)。

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

取代专有 CTag 扩展的官方标准实际上是 DAV-Sync 又名 RFC 6578。sync-token 属性 和 header 取代了 CTag header.

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

我注意到 CTag 是顺序的

CTags 不是连续的,它们是不透明的标记。特定的服务器可能会使用一个序列,但这完全是任意的。 (所有DAV代币也是如此,它们总是不透明的)