[CalendarServer-changes] [2617] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Mon Jun 23 13:31:53 PDT 2008


Revision: 2617
          http://trac.macosforge.org/projects/calendarserver/changeset/2617
Author:   dreid at apple.com
Date:     2008-06-23 13:31:53 -0700 (Mon, 23 Jun 2008)
Log Message:
-----------
Include the hash of the directoryrecord in the decision about the cache being stale.  This way changes in enabledForCalendaring will be reflected by the cache.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/cache.py
    CalendarServer/trunk/twistedcaldav/directory/directory.py
    CalendarServer/trunk/twistedcaldav/test/test_cache.py

Modified: CalendarServer/trunk/twistedcaldav/cache.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/cache.py	2008-06-23 16:06:17 UTC (rev 2616)
+++ CalendarServer/trunk/twistedcaldav/cache.py	2008-06-23 20:31:53 UTC (rev 2617)
@@ -58,6 +58,7 @@
         return succeed(response)
 
 
+
 class URINotFoundException(Exception):
     def __init__(self, uri):
         self.uri = uri
@@ -69,6 +70,7 @@
             self.uri)
 
 
+
 class MemcacheChangeNotifier(LoggingMixIn, CachePoolUserMixIn):
     def __init__(self, resource, cachePool=None):
         self._resource = resource
@@ -102,14 +104,27 @@
         return str(principal.children[0])
 
 
-    def _canonicalizeURIForRequest(self, uri, request):
-        def _uriNotFound(f):
-            f.trap(AttributeError)
+    def _uriNotFound(self, f, uri):
+        f.trap(AttributeError)
+        raise URINotFoundException(uri)
+
+
+    def _getRecordForURI(self, uri, request):
+        def _getRecord(resrc):
+            if hasattr(resrc, 'record'):
+                return resrc.record
+
+        try:
+            return request.locateResource(uri).addCallback(
+                _getRecord).addErrback(self._uriNotFound, uri)
+        except AssertionError:
             raise URINotFoundException(uri)
 
+
+    def _canonicalizeURIForRequest(self, uri, request):
         try:
             return request.locateResource(uri).addCallback(
-                lambda resrc: resrc.url()).addErrback(_uriNotFound)
+                lambda resrc: resrc.url()).addErrback(self._uriNotFound, uri)
         except AssertionError:
             raise URINotFoundException(uri)
 
@@ -177,9 +192,11 @@
         def _tokensForURIs((pURI, rURI)):
             tokens = []
             d1 = self._tokenForURI(pURI)
-            d1.addCallback(lambda pToken: tokens.append(pToken))
+            d1.addCallback(tokens.append)
+            d1.addCallback(lambda _ign: self._getRecordForURI(pURI, request))
+            d1.addCallback(lambda dToken: tokens.append(hash(dToken)))
             d1.addCallback(lambda _ign: self._tokenForURI(rURI))
-            d1.addCallback(lambda uToken: tokens.append(uToken))
+            d1.addCallback(tokens.append)
             d1.addCallback(lambda _ign: tokens)
             return d1
 
@@ -213,6 +230,14 @@
 
             if curTokens[1] != expectedTokens[1]:
                 self.log_debug(
+                    "Directory Record Token doesn't match for %r: %r != %r" % (
+                        request.cacheKey,
+                        curTokens[1],
+                        expectedTokens[1]))
+                return None
+
+            if curTokens[2] != expectedTokens[2]:
+                self.log_debug(
                     "URI token doesn't match for %r: %r != %r" % (
                         request.cacheKey,
                         curTokens[1],
@@ -234,11 +259,15 @@
 
             self.log_debug("Found in cache: %r = %r" % (key, value))
 
-            (principalToken, uriToken,
+            (principalToken, directoryToken, uriToken,
              resp) = cPickle.loads(value)
             d2 = self._getTokens(request)
 
-            d2.addCallback(_checkTokens, (principalToken, uriToken), resp)
+            d2.addCallback(_checkTokens,
+                           (principalToken,
+                            directoryToken,
+                            uriToken),
+                           resp)
 
             return d2
 
@@ -259,9 +288,10 @@
 
 
     def cacheResponseForRequest(self, request, response):
-        def _makeCacheEntry((pToken, uToken), (key, responseBody)):
+        def _makeCacheEntry((pToken, dToken, uToken), (key, responseBody)):
             cacheEntry = cPickle.dumps(
                 (pToken,
+                 dToken,
                  uToken,
                  (response.code,
                   dict(list(response.headers.getAllRawHeaders())),

Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py	2008-06-23 16:06:17 UTC (rev 2616)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py	2008-06-23 20:31:53 UTC (rev 2617)
@@ -190,8 +190,10 @@
 
     def __hash__(self):
         h = hash(self.__class__)
-        for attr in ("service", "recordType", "shortName", "guid"):
+        for attr in ("service", "recordType", "shortName", "guid",
+                     "enabledForCalendaring"):
             h = (h + hash(getattr(self, attr))) & sys.maxint
+
         return h
 
     def members(self):

Modified: CalendarServer/trunk/twistedcaldav/test/test_cache.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_cache.py	2008-06-23 16:06:17 UTC (rev 2616)
+++ CalendarServer/trunk/twistedcaldav/test/test_cache.py	2008-06-23 20:31:53 UTC (rev 2617)
@@ -77,9 +77,11 @@
 
 
 class StubURLResource(object):
-    def __init__(self, url):
+    def __init__(self, url, record=None):
         self._url = url
 
+        if record is not None:
+            self.record = record
 
     def url(self):
         return self._url
@@ -129,11 +131,11 @@
             '/calendars/users/cdaboo/': StubURLResource(
                 '/calendars/__uids__/cdaboo/'),
             '/principals/__uids__/cdaboo/': StubURLResource(
-                '/principals/__uids__/cdaboo/'),
+                '/principals/__uids__/cdaboo/', record='directoryToken0'),
             '/calendars/__uids__/dreid/': StubURLResource(
                 '/calendars/__uids__/dreid/'),
             '/principals/__uids__/dreid/': StubURLResource(
-                '/principals/__uids__/dreid/')}
+                '/principals/__uids__/dreid/', record='directoryToken0')}
 
 
     def tearDown(self):
@@ -157,9 +159,6 @@
             '/calendars/users/cdaboo/',
             '/principals/__uids__/cdaboo/')
 
-        request.resources['/calendars/users/cdaboo/'] = StubURLResource(
-            '/calendars/__uids__/cdaboo/')
-
         d = self.rc.getResponseForRequest(request)
 
         d.addCallback(self.assertEquals, None)
@@ -183,9 +182,6 @@
             '/calendars/__uids__/cdaboo/',
             '/principals/users/cdaboo/')
 
-        request.resources['/principals/users/cdaboo/'] = StubURLResource(
-            '/principals/__uids__/cdaboo/')
-
         d = self.rc.getResponseForRequest(request)
 
         d.addCallback(self.assertEquals, None)
@@ -286,7 +282,6 @@
         return d
 
 
-
     def test_cacheResponseForRequest(self):
         expected_response = StubResponse(200, {}, "Foobar")
 
@@ -304,10 +299,6 @@
             return d1
 
 
-        StubRequest.resources[
-            '/principals/__uids__/dreid/'] = StubURLResource(
-            '/principals/__uids__/dreid/')
-
         d = self.rc.cacheResponseForRequest(
             StubRequest('PROPFIND',
                         '/principals/__uids__/dreid/',
@@ -318,7 +309,21 @@
         return d
 
 
+    def test_recordHashChangeInvalidatesCache(self):
+        StubRequest.resources[
+            '/principals/__uids__/cdaboo/'].record = 'directoryToken1'
 
+        d = self.rc.getResponseForRequest(
+            StubRequest(
+                'PROPFIND',
+                '/calendars/__uids__/cdaboo/',
+                '/principals/__uids__/cdaboo/'))
+
+        d.addCallback(self.assertEquals, None)
+        return d
+
+
+
 class MemcacheResponseCacheTests(BaseCacheTestMixin, TestCase):
     def setUp(self):
         super(MemcacheResponseCacheTests, self).setUp()
@@ -351,6 +356,7 @@
             0, #flags
             cPickle.dumps((
             'principalToken0',
+            hash('directoryToken0'),
             'uriToken0',
             (self.expected_response[0],
              dict(list(self.expected_response[1].getAllRawHeaders())),
@@ -376,6 +382,7 @@
             0, #flags
             cPickle.dumps((
                     'principalToken0',
+                    hash('directoryToken0'),
                     'uriToken0',
                     (expected_response[0],
                      dict(list(expected_response[1].getAllRawHeaders())),
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080623/c68ce50f/attachment.htm 


More information about the calendarserver-changes mailing list