[CalendarServer-changes] [5118] CalendarServer/branches/users/wsanchez/deployment/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Mon Feb 15 08:25:28 PST 2010


Revision: 5118
          http://trac.macosforge.org/projects/calendarserver/changeset/5118
Author:   cdaboo at apple.com
Date:     2010-02-15 08:25:26 -0800 (Mon, 15 Feb 2010)
Log Message:
-----------
Avoid a race-condition between two simultaneous PUTs with If-Match headers.

Modified Paths:
--------------
    CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/memcacheprops.py
    CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/method/put_common.py

Modified: CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/memcacheprops.py
===================================================================
--- CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/memcacheprops.py	2010-02-15 16:09:09 UTC (rev 5117)
+++ CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/memcacheprops.py	2010-02-15 16:25:26 UTC (rev 5118)
@@ -265,6 +265,10 @@
             if not result:
                 raise MemcacheError("Unable to flush cache on %s" % (child,))
 
+    def reloadCache(self, child):
+        loaded = self._loadCache(childNames=(child.fp.basename(),))
+        self.propertyCache().update(loaded.iteritems())
+
     def propertyStoreForChild(self, child, childPropertyStore):
         return self.ChildPropertyStore(self, child, childPropertyStore)
 
@@ -283,6 +287,9 @@
         def flushCache(self):
             self.parentPropertyCollection.flushCache(self.child)
 
+        def reloadCache(self):
+            self.parentPropertyCollection.reloadCache(self.child)
+
         def get(self, qname, cache=True):
             if cache:
                 propertyCache = self.propertyCache()

Modified: CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/method/put_common.py	2010-02-15 16:09:09 UTC (rev 5117)
+++ CalendarServer/branches/users/wsanchez/deployment/twistedcaldav/method/put_common.py	2010-02-15 16:25:26 UTC (rev 5118)
@@ -27,7 +27,7 @@
 from twisted.internet.defer import waitForDeferred
 from twisted.python import failure
 from twisted.python.filepath import FilePath
-from twisted.web2 import responsecode
+from twisted.web2 import responsecode, http
 from twisted.web2.dav import davxml
 from twisted.web2.dav.element.base import dav_namespace
 from twisted.web2.dav.element.base import PCDATAElement
@@ -458,7 +458,15 @@
             
             if destination_uri and not reserved:
                 raise HTTPError(StatusResponse(responsecode.CONFLICT, "Resource: %s currently in use." % (destination_uri,)))
-        
+
+            # Re-evaluate the HTTP pre-conditions (If-Match etc) after acquiring the UID lock. This avoids
+            # a race condition where two simultaneous PUTs with If-Match can conflict (i.e. second PUT does
+            # not fail even though underlying resource was changed by first PUT). We also need to reload the
+            # property cache before we do this as the etag property may have changed.
+            if destination.exists():
+                destination.deadProperties().reloadCache()
+            destination.checkPreconditions(request)
+
             # uid conflict check - note we do this after reserving the UID to avoid a race condition where two requests
             # try to write the same calendar data to two different resource URIs.
             if not isiTIP:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100215/362be2d6/attachment.html>


More information about the calendarserver-changes mailing list