[CalendarServer-changes] [4144] CalendarServer/trunk/twistedcaldav/memcacheprops.py

source_changes at macosforge.org source_changes at macosforge.org
Sat May 2 17:31:29 PDT 2009


Revision: 4144
          http://trac.macosforge.org/projects/calendarserver/changeset/4144
Author:   sagen at apple.com
Date:     2009-05-02 17:31:27 -0700 (Sat, 02 May 2009)
Log Message:
-----------
MemcachePropertyCollection's setProperty( ) and deleteProperty( ) now honor the memcached check-and-set token mismatch error, refetching+retrying if they run into it.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/memcacheprops.py

Modified: CalendarServer/trunk/twistedcaldav/memcacheprops.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/memcacheprops.py	2009-05-02 20:33:07 UTC (rev 4143)
+++ CalendarServer/trunk/twistedcaldav/memcacheprops.py	2009-05-03 00:31:27 UTC (rev 4144)
@@ -198,31 +198,57 @@
 
         return cache
 
-    def setProperty(self, child, property):
+    def setProperty(self, child, property, delete=False):
         propertyCache, key, childCache, token = self.childCache(child)
 
-        if childCache.get(property.qname(), None) == property:
-            # No changes
-            return
+        if delete:
+            qname = property
+            if childCache.has_key(qname):
+                del childCache[qname]
+        else:
+            qname = property.qname()
+            childCache[qname] = property
 
-        childCache[property.qname()] = property
+        client = self.memcacheClient()
 
-        client = self.memcacheClient()
         if client is not None:
-            try:
-                result = client.set(key, childCache, time=self.cacheTimeout, token=token)
-            except TokenMismatchError:
-                # The value in memcache has changed since we last fetched it,
-                log.error("memcacheprops setProperty( ) TokenMismatchError")
-                result = False
+            retries = 10
+            while retries:
+                try:
+                    if client.set(key, childCache, time=self.cacheTimeout,
+                        token=token):
+                        # Success
+                        break
 
-            if not result:
+                except TokenMismatchError:
+                    # The value in memcache has changed since we last
+                    # fetched it
+                    log.debug("memcacheprops setProperty TokenMismatchError; retrying...")
+
+                finally:
+                    # Re-fetch the properties for this child
+                    loaded = self._loadCache(childNames=(child.fp.basename(),))
+                    propertyCache.update(loaded.iteritems())
+
+                retries -= 1
+
+                propertyCache, key, childCache, token = self.childCache(child)
+
+                if delete:
+                    if childCache.has_key(qname):
+                        del childCache[qname]
+                else:
+                    childCache[qname] = property
+
+            else:
+                log.error("memcacheprops setProperty had too many failures")
                 delattr(self, "_propertyCache")
-                raise MemcacheError("Unable to set property %s on %s"
-                                    % (property.sname(), child))
+                raise MemcacheError("Unable to %s property {%s}%s on %s"
+                    % ("delete" if delete else "set",
+                    qname[0], qname[1], child))
 
-            loaded = self._loadCache(childNames=(child.fp.basename(),))
-            propertyCache.update(loaded.iteritems())
+    def deleteProperty(self, child, qname):
+        return self.setProperty(child, qname, delete=True)
 
     def flushCache(self, child):
         path = child.fp.path
@@ -238,28 +264,6 @@
             if not result:
                 raise MemcacheError("Unable to flush cache on %s" % (child,))
 
-    def deleteProperty(self, child, qname):
-        propertyCache, key, childCache, token = self.childCache(child)
-
-        del childCache[qname]
-
-        client = self.memcacheClient()
-        if client is not None:
-            try:
-                result = client.set(key, childCache, time=self.cacheTimeout, token=token)
-            except TokenMismatchError:
-                # The value in memcache has changed since we last fetched it
-                log.error("memcacheprops deleteProperty( ) TokenMismatchError")
-                result = False
-
-            if not result:
-                delattr(self, "_propertyCache")
-                raise MemcacheError("Unable to delete property {%s}%s on %s"
-                                    % (qname[0], qname[1], child))
-
-            loaded = self._loadCache(childNames=(child.fp.basename(),))
-            propertyCache.update(loaded.iteritems())
-
     def propertyStoreForChild(self, child, childPropertyStore):
         return self.ChildPropertyStore(self, child, childPropertyStore)
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090502/fe317f79/attachment.html>


More information about the calendarserver-changes mailing list