[CalendarServer-changes] [3981] CalendarServer/branches/users/wsanchez/mo-cache

source_changes at macosforge.org source_changes at macosforge.org
Sat Apr 11 11:03:42 PDT 2009


Revision: 3981
          http://trac.macosforge.org/projects/calendarserver/changeset/3981
Author:   wsanchez at apple.com
Date:     2009-04-11 11:03:42 -0700 (Sat, 11 Apr 2009)
Log Message:
-----------
Rework CachingXattrPropertyStore as CachingPropertyStore, which can wrap any underlying property store.

Children of calendar collections are now monkeypatched to use a MemcachePropertyCollection on the calendar collection, so that they have can share a memcache thingo.

Modified Paths:
--------------
    CalendarServer/branches/users/wsanchez/mo-cache/calendarserver/provision/root.py
    CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/extensions.py
    CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/static.py

Modified: CalendarServer/branches/users/wsanchez/mo-cache/calendarserver/provision/root.py
===================================================================
--- CalendarServer/branches/users/wsanchez/mo-cache/calendarserver/provision/root.py	2009-04-11 18:00:31 UTC (rev 3980)
+++ CalendarServer/branches/users/wsanchez/mo-cache/calendarserver/provision/root.py	2009-04-11 18:03:42 UTC (rev 3981)
@@ -28,9 +28,10 @@
 from twisted.web2.auth.wrapper import UnauthorizedResponse
 from twisted.web.xmlrpc import Proxy
 
-from twistedcaldav.extensions import DAVFile, CachingXattrPropertyStore
+from twistedcaldav.extensions import DAVFile, CachingPropertyStore
 from twistedcaldav.extensions import DirectoryPrincipalPropertySearchMixIn
 from twistedcaldav.extensions import ReadOnlyResourceMixIn
+from twistedcaldav.memcacheprops import MemcachePropertyStore
 from twistedcaldav.config import config
 from twistedcaldav.log import Logger
 from twistedcaldav.cache import _CachedResponseResource
@@ -81,11 +82,17 @@
                 return response
             self.contentFilters.append((addConnectionClose, True))
 
-
     def deadProperties(self):
+        # FIXME: Same as in static.py's CalDAVFile
         if not hasattr(self, "_dead_properties"):
-            self._dead_properties = CachingXattrPropertyStore(self)
+            # Get the property store from super
+            deadProperties = super(RootResource, self).deadProperties()
 
+            # Wrap the property store in a memory store
+            deadProperties = CachingPropertyStore(deadProperties)
+
+            self._dead_properties = deadProperties
+
         return self._dead_properties
 
     def defaultAccessControlList(self):

Modified: CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/extensions.py	2009-04-11 18:00:31 UTC (rev 3980)
+++ CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/extensions.py	2009-04-11 18:03:42 UTC (rev 3981)
@@ -51,7 +51,6 @@
 from twisted.web2.dav.resource import DAVResource as SuperDAVResource
 from twisted.web2.dav.resource import DAVPrincipalResource as SuperDAVPrincipalResource
 from twisted.web2.dav.util import joinURL
-from twisted.web2.dav.xattrprops import xattrPropertyStore
 from twisted.web2.dav.method import prop_common
 from twisted.web2.dav.method.report import max_number_of_matches
 
@@ -469,7 +468,6 @@
     """
     Extended L{twisted.web2.dav.resource.DAVResource} implementation.
     """
-
     def renderHTTP(self, request):
         log.info("%s %s %s" % (request.method, urllib.unquote(request.uri), "HTTP/%s.%s" % request.clientproto))
         return super(DAVResource, self).renderHTTP(request)
@@ -1052,19 +1050,21 @@
         HTTPError.__init__(self,
             StatusResponse(
                 responsecode.NOT_FOUND,
-                "No such property: %s" % (qname,)
+                "No such property: {%s}%s" % qname
             )
         )
 
-class CachingXattrPropertyStore(xattrPropertyStore, LoggingMixIn):
+class CachingPropertyStore (LoggingMixIn):
     """
-    A Property Store that caches attributes from the xattrs.
+    DAV property store using a dict in memory on top of another
+    property store implementation.
     """
-    def __init__(self, resource):
-        super(CachingXattrPropertyStore, self).__init__(resource)
+    def __init__(self, propertyStore):
+        self.propertyStore = propertyStore
+        self.resource = propertyStore.resource
 
     def get(self, qname):
-        self.log_debug("Get: %r, %r" % (self.resource.fp.path, qname))
+        #self.log_debug("Get: %r, %r" % (self.resource.fp.path, qname))
 
         cache = self._cache()
 
@@ -1073,30 +1073,27 @@
             if property is None:
                 self.log_debug("Cache miss: %r, %r, %r" % (self, self.resource.fp.path, qname))
                 try:
-                    property = super(CachingXattrPropertyStore, self).get(qname)
+                    property = self.propertyStore.get(qname)
                 except HTTPError:
-                    self.log_debug("Cache double miss: %r, %r, %r" % (self, self.resource.fp.path, qname))
                     del cache[qname]
                     raise PropertyNotFoundError(qname)
                 cache[qname] = property
-            else:
-                self.log_debug("Cache hit: %r, %r, %r" % (self, self.resource.fp.path, qname))
 
             return property
         else:
             raise PropertyNotFoundError(qname)
 
     def set(self, property):
-        self.log_debug("Set: %r, %r" % (self.resource.fp.path, property))
+        #self.log_debug("Set: %r, %r" % (self.resource.fp.path, property))
 
         cache = self._cache()
 
         cache[property.qname()] = None
-        super(CachingXattrPropertyStore, self).set(property)
+        self.propertyStore.set(property)
         cache[property.qname()] = property
 
     def contains(self, qname):
-        self.log_debug("Contains: %r, %r" % (self.resource.fp.path, qname))
+        #self.log_debug("Contains: %r, %r" % (self.resource.fp.path, qname))
 
         try:
             cache = self._cache()
@@ -1107,28 +1104,29 @@
                 raise
 
         if qname in cache:
-            self.log_debug("Contains cache hit: %r, %r, %r" % (self, self.resource.fp.path, qname))
+            #self.log_debug("Contains cache hit: %r, %r, %r" % (self, self.resource.fp.path, qname))
             return True
         else:
             return False
 
     def delete(self, qname):
-        self.log_debug("Delete: %r, %r" % (self.resource.fp.path, qname))
+        #self.log_debug("Delete: %r, %r" % (self.resource.fp.path, qname))
 
         if self._data is not None and qname in self._data:
             del self._data[qname]
 
-        super(CachingXattrPropertyStore, self).delete(qname)
+        self.propertyStore.delete(qname)
 
     def list(self):
-        self.log_debug("List: %r" % (self.resource.fp.path,))
+        #self.log_debug("List: %r" % (self.resource.fp.path,))
         return self._cache().iterkeys()
 
     def _cache(self):
         if not hasattr(self, "_data"):
+            #self.log_debug("Cache init: %r" % (self.resource.fp.path,))
             self._data = dict(
                 (name, None)
-                for name in super(CachingXattrPropertyStore, self).list()
+                for name in self.propertyStore.list()
             )
         return self._data
 

Modified: CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/static.py	2009-04-11 18:00:31 UTC (rev 3980)
+++ CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/static.py	2009-04-11 18:03:42 UTC (rev 3981)
@@ -39,8 +39,7 @@
 import errno
 from urlparse import urlsplit
 
-from twisted.internet.defer import fail, succeed, inlineCallbacks, returnValue,\
-    maybeDeferred
+from twisted.internet.defer import fail, succeed, inlineCallbacks, returnValue, maybeDeferred
 from twisted.python.failure import Failure
 from twisted.web2 import responsecode, http, http_headers
 from twisted.web2.http import HTTPError, StatusResponse
@@ -57,9 +56,9 @@
 from twistedcaldav import customxml
 from twistedcaldav.caldavxml import caldav_namespace
 from twistedcaldav.config import config
-from twistedcaldav.customxml import TwistedCalendarAccessProperty,\
-    TwistedScheduleMatchETags
-from twistedcaldav.extensions import DAVFile, CachingXattrPropertyStore
+from twistedcaldav.customxml import TwistedCalendarAccessProperty, TwistedScheduleMatchETags
+from twistedcaldav.extensions import DAVFile, CachingPropertyStore
+from twistedcaldav.memcacheprops import MemcachePropertyStore, MemcachePropertyCollection
 from twistedcaldav.freebusyurl import FreeBusyURLResource
 from twistedcaldav.ical import Component as iComponent
 from twistedcaldav.ical import Property as iProperty
@@ -142,12 +141,7 @@
 
         return super(CalDAVFile, self).checkPreconditions(request)
 
-    def deadProperties(self):
-        if not hasattr(self, "_dead_properties"):
-            self._dead_properties = CachingXattrPropertyStore(self)
 
-        return self._dead_properties
-
     ##
     # CalDAV
     ##
@@ -375,6 +369,29 @@
             if not child.startswith(".")
         ]
 
+    def propertyCollection(self):
+        if not hasattr(self, "_propertyCollection"):
+            self._propertyCollection = MemcachePropertyCollection(self)
+        return self._propertyCollection
+
+    def createSimilarFile(self, path):
+        if path == self.fp.path:
+            return self
+
+        similar = super(CalDAVFile, self).createSimilarFile(path)
+
+        if isCalendarCollectionResource(self):
+            superDeadProperties = similar.deadProperties
+
+            def deadProperties():
+                if not hasattr(similar, "_dead_properties"):
+                    similar._dead_properties = self.propertyCollection().propertyStoreForChild(similar, superDeadProperties())
+                return similar._dead_properties
+
+            similar.deadProperties = deadProperties
+
+        return similar
+
     def updateCTag(self):
         assert self.isCollection()
         try:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090411/913a295a/attachment-0001.html>


More information about the calendarserver-changes mailing list