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

时间:2017-12-14 15:18:39

标签: webdav carddav

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

对于这个文件夹,我有ETag(SabreDAV方言中的CTag,用于区分文件夹etags和项etags)。如果CTag发生了变化,我需要再次重新同步。但是如果这个改变是由我自己引起的(例如我刚刚将一个联系人上传到这个CardDAV文件夹中),是不是有办法避免重新同步?

理想情况下,我希望DAV服务器在每次更改服务器上任何内容的请求时返回此信息:

  • CTag1,当前文件夹的CTag,就像我的行动被应用之前一样
  • CTag2,应用我的操作后当前文件夹的CTag
  • ETag分配给相关项目(虽然它与此特定问题无关)。

这将让我了解CTag更改是否仅由我自己的操作引起(并且不需要重新同步)或其间发生了其他事情(因此需要重新同步)。

目前,我只能在任何时候查询文件夹中的CTag,但我不知道如果CTag改变了怎么办(伪代码):

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

cTag2显然与cTag1不同,但这提供了关于中间是否发生其他事情的零信息(另一个客户端在同一文件夹中更改了某些内容)。所以,cTag0<> cTag1比较不会让我免于竞争条件,我可以认为我是同步的,而其他一些更新却没有引起注意。

很高兴:

DECLARE @TeacherID1 INT = 1
DECLARE @TeacherID2 INT = 2

SELECT 
    StudentID = T1.s_id,
    Teacher1 = T1.t_id,
    Teacher1ClassTime = T1.class_time ,
    Teacher2 = T2.t_id,
    Teacher2ClassTime = T2.class_time 
FROM 
    TeachingTable T1
    INNER JOIN TeachingTable T2 ON T2.s_id=T1._sid AND T2.t_id=@TeacherID2
WHERE 
    T1.t_id = @TeacherID1
ORDER BY
    T1.ClassTime

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

编辑:我想到的一个想法。我注意到CTag是连续的。这是一个数字,在每次操作文件夹时都会增加1。因此,如果在获得CTag之间增加超过1,进行我的操作然后再次获得CTag,这将表明其他事情刚刚发生。但这似乎并不可靠,我担心它依赖于这种行为的实现特定。寻找更强大的解决方案。

1 个答案:

答案 0 :(得分:1)

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

这非常相似 How to avoid time conflict or overlap for CalDAV?

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

还有Calendar Server Bulk Change Requests for *DAV Protocols 这是一些服务器支持的,它提供了一种更具体的方法来实现这一点。 由于它不是RFC,我不建议依赖它。

所以你可能会做的是PUT。如果它返回ETag,你很好并且可以通过同步集合来协调(通过任何机制,PROPFIND:1,CTag或sync-report)。如果,您可以选择通过其他方式进行协调(例如,比较/散列内容),或者只是将更改视为并发编辑,我认为大多数实现都会这样做。

如果你很幸运,服务器也可以在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集合内容,这些内容与此不同。 WebDAV集合通常也有内容(可以通过GET等检索),ETag对应。

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

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

我注意到CTag是顺序的

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