[CalendarServer-changes] [6281] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Sep 13 11:16:52 PDT 2010


Revision: 6281
          http://trac.macosforge.org/projects/calendarserver/changeset/6281
Author:   sagen at apple.com
Date:     2010-09-13 11:16:50 -0700 (Mon, 13 Sep 2010)
Log Message:
-----------
Speed up the xmlfile implementation of DirectoryService by indexing records as the XML is parsed.

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/tap/util.py
    CalendarServer/trunk/calendarserver/tools/test/deprovision/caldavd.plist
    CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist
    CalendarServer/trunk/calendarserver/tools/test/principals/caldavd.plist
    CalendarServer/trunk/calendarserver/tools/test/test_gateway.py
    CalendarServer/trunk/twistedcaldav/directory/directory.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py
    CalendarServer/trunk/twistedcaldav/directory/xmlfile.py
    CalendarServer/trunk/twistedcaldav/stdconfig.py

Modified: CalendarServer/trunk/calendarserver/tap/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/util.py	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/calendarserver/tap/util.py	2010-09-13 18:16:50 UTC (rev 6281)
@@ -130,6 +130,19 @@
     directoryBackedAddressBookResourceClass = DirectoryBackedAddressBookResource
 
     #
+    # Setup the Augment Service
+    #
+    augmentClass = namedClass(config.AugmentService.type)
+
+    log.info("Configuring augment service of type: %s" % (augmentClass,))
+
+    try:
+        augment.AugmentService = augmentClass(**config.AugmentService.params)
+    except IOError:
+        log.error("Could not start augment service")
+        raise
+
+    #
     # Setup the Directory
     #
     directories = []
@@ -212,19 +225,6 @@
         pass
 
     #
-    # Setup the Augment Service
-    #
-    augmentClass = namedClass(config.AugmentService.type)
-
-    log.info("Configuring augment service of type: %s" % (augmentClass,))
-
-    try:
-        augment.AugmentService = augmentClass(**config.AugmentService.params)
-    except IOError:
-        log.error("Could not start augment service")
-        raise
-
-    #
     # Setup the ProxyDB Service
     #
     proxydbClass = namedClass(config.ProxyDBService.type)

Modified: CalendarServer/trunk/calendarserver/tools/test/deprovision/caldavd.plist
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/deprovision/caldavd.plist	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/calendarserver/tools/test/deprovision/caldavd.plist	2010-09-13 18:16:50 UTC (rev 6281)
@@ -172,8 +172,6 @@
             <string>resources</string>
             <string>locations</string>
         </array>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
       </dict>
     </dict>
     

Modified: CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/calendarserver/tools/test/gateway/caldavd.plist	2010-09-13 18:16:50 UTC (rev 6281)
@@ -172,8 +172,6 @@
             <string>resources</string>
             <string>locations</string>
         </array>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
       </dict>
     </dict>
     

Modified: CalendarServer/trunk/calendarserver/tools/test/principals/caldavd.plist
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/principals/caldavd.plist	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/calendarserver/tools/test/principals/caldavd.plist	2010-09-13 18:16:50 UTC (rev 6281)
@@ -172,8 +172,6 @@
             <string>resources</string>
             <string>locations</string>
         </array>
-        <key>cacheTimeout</key>
-        <integer>30</integer>
       </dict>
     </dict>
     

Modified: CalendarServer/trunk/calendarserver/tools/test/test_gateway.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_gateway.py	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/calendarserver/tools/test/test_gateway.py	2010-09-13 18:16:50 UTC (rev 6281)
@@ -234,6 +234,7 @@
         directory = getDirectory()
 
         yield self.runCommand(command_createResource)
+        directory.flushCaches()
         record = directory.recordWithUID("AF575A61-CFA6-49E1-A0F6-B5662C9D9801")
         self.assertEquals(record.fullName, "Laptop 1")
 

Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py	2010-09-13 18:16:50 UTC (rev 6281)
@@ -148,7 +148,10 @@
         raise NotImplementedError("Subclass must implement listRecords()")
 
     def recordWithShortName(self, recordType, shortName):
-        raise NotImplementedError("Subclass must implement recordWithShortName()")
+        for record in self.listRecords(recordType):
+            if shortName in record.shortNames:
+                return record
+        return None
 
     def recordWithUID(self, uid):
         for record in self.allRecords():

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipalmembers.py	2010-09-13 18:16:50 UTC (rev 6281)
@@ -38,8 +38,8 @@
     def setUp(self):
         super(ProxyPrincipals, self).setUp()
 
-        self.directoryService = XMLDirectoryService({'xmlFile' : xmlFile})
         augment.AugmentService = augment.AugmentXMLDB(xmlFiles=(augmentsFile.path,))
+        self.directoryService = XMLDirectoryService({'xmlFile' : xmlFile})
         calendaruserproxy.ProxyDBService = calendaruserproxy.ProxySqliteDB("proxies.sqlite")
 
         # Set up a principals hierarchy for each service we're testing with
@@ -436,12 +436,8 @@
 
                 delRec = self.directoryService.recordWithShortName(
                     DirectoryService.recordType_users, "dreid")
-                for cache in self.directoryService._recordCaches.itervalues():
-                    cache.removeRecord(delRec)
-                del self.directoryService._accounts()[
-                    DirectoryService.recordType_users]["dreid"]
+                self.directoryService._removeFromIndex(delRec)
 
-
                 cacheTimeout = config.DirectoryService.params.get("cacheTimeout", 30) * 60 * 2
 
                 @inlineCallbacks
@@ -475,10 +471,7 @@
                     self.assertEquals(len(members), 2)
 
                     # Restore removed user
-                    parser = XMLAccountsParser(self.directoryService.xmlFile)
-                    self.directoryService._parsedAccounts = parser.items
-                    self.directoryService.recordWithShortName(
-                        DirectoryService.recordType_users, "dreid")
+                    self.directoryService._forceReload()
 
                     # Trigger the proxy DB clean up, which will actually
                     # remove the deletion timer because the principal has been
@@ -492,10 +485,7 @@
                     # Remove the dreid user from the directory service
                     delRec = self.directoryService.recordWithShortName(
                         DirectoryService.recordType_users, "dreid")
-                    for cache in self.directoryService._recordCaches.itervalues():
-                        cache.removeRecord(delRec)
-                    del self.directoryService._accounts()[
-                        DirectoryService.recordType_users]["dreid"]
+                    self.directoryService._removeFromIndex(delRec)
 
                     # Trigger the proxy DB clean up, which won't actually
                     # remove anything because we haven't exceeded the timeout
@@ -523,8 +513,7 @@
                     yield _membershipTest()
 
                 # Restore removed user
-                parser = XMLAccountsParser(self.directoryService.xmlFile)
-                self.directoryService._parsedAccounts = parser.items
+                self.directoryService._forceReload()
 
                 yield self._clearProxy(principal, proxyType)
                 yield self._clearProxy(fakePrincipal, proxyType)

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_xmlfile.py	2010-09-13 18:16:50 UTC (rev 6281)
@@ -97,9 +97,9 @@
     Test XML file based directory implementation.
     """
     def service(self):
-        directory = XMLDirectoryService({'xmlFile' : self.xmlFile()}, alwaysStat=True)
         self.patch(augment, "AugmentService",
                    augment.AugmentXMLDB(xmlFiles=(self.augmentsFile().path,)))
+        directory = XMLDirectoryService({'xmlFile' : self.xmlFile()}, alwaysStat=True)
         return directory
 
     def test_changedXML(self):
@@ -289,6 +289,14 @@
         self.assertEquals(record, None)
 
 
+    def test_indexing(self):
+        service = self.service()
+        self.assertNotEquals(None, service._lookupInIndex(service.recordType_users, service.INDEX_TYPE_SHORTNAME, "usera"))
+        self.assertNotEquals(None, service._lookupInIndex(service.recordType_users, service.INDEX_TYPE_CUA, "mailto:wsanchez at example.com"))
+        self.assertNotEquals(None, service._lookupInIndex(service.recordType_users, service.INDEX_TYPE_GUID, "9FF60DAD-0BDE-4508-8C77-15F0CA5C8DD2"))
+        self.assertNotEquals(None, service._lookupInIndex(service.recordType_locations, service.INDEX_TYPE_SHORTNAME, "orion"))
+        self.assertEquals(None, service._lookupInIndex(service.recordType_users, service.INDEX_TYPE_CUA, "mailto:nobody at example.com"))
+
 class XMLFileSubset (XMLFileBase, TestCase):
     """
     Test the recordTypes subset feature of XMLFile service.
@@ -299,6 +307,8 @@
     ))
 
     def test_recordTypesSubset(self):
+        self.patch(augment, "AugmentService",
+                   augment.AugmentXMLDB(xmlFiles=(self.augmentsFile().path,)))
         directory = XMLDirectoryService(
             {'xmlFile' : self.xmlFile(), 
              'recordTypes' : (DirectoryService.recordType_users, 
@@ -306,3 +316,4 @@
             alwaysStat=True
         )
         self.assertEquals(set(("users", "groups")), set(directory.recordTypes()))
+    

Modified: CalendarServer/trunk/twistedcaldav/directory/xmlfile.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/xmlfile.py	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/twistedcaldav/directory/xmlfile.py	2010-09-13 18:16:50 UTC (rev 6281)
@@ -33,15 +33,16 @@
 
 from twistedcaldav.config import fullServerPath
 from twistedcaldav.directory import augment
-from twistedcaldav.directory.directory import DirectoryService, DirectoryError
+from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord, DirectoryError
 from twistedcaldav.directory.cachingdirectory import CachingDirectoryService,\
     CachingDirectoryRecord
 from twistedcaldav.directory.xmlaccountsparser import XMLAccountsParser, XMLAccountRecord
+from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
 import xml.etree.ElementTree as ET
 from uuid import uuid4
 
 
-class XMLDirectoryService(CachingDirectoryService):
+class XMLDirectoryService(DirectoryService):
     """
     XML based implementation of L{IDirectoryService}.
     """
@@ -49,6 +50,12 @@
 
     realmName = None
 
+    INDEX_TYPE_GUID      = "guid"
+    INDEX_TYPE_SHORTNAME = "shortname"
+    INDEX_TYPE_CUA       = "cua"
+    INDEX_TYPE_AUTHID    = "authid"
+
+
     def __repr__(self):
         return "<%s %r: %r>" % (self.__class__.__name__, self.realmName, self.xmlFile)
 
@@ -63,7 +70,6 @@
                 self.recordType_locations,
                 self.recordType_resources,
             ),
-            'cacheTimeout' : 30,
             'realmName' : '/Search',
         }
         ignored = None
@@ -72,7 +78,7 @@
         self._recordTypes = params['recordTypes']
         self.realmName = params['realmName']
 
-        super(XMLDirectoryService, self).__init__(params['cacheTimeout'])
+        super(XMLDirectoryService, self).__init__()
 
         xmlFile = fullServerPath(config.DataRoot, params.get("xmlFile"))
         if type(xmlFile) is str:
@@ -108,68 +114,166 @@
         self._lastCheck = 0
         self._alwaysStat = alwaysStat
         self.directoryBackedAddressBook = params.get('directoryBackedAddressBook')
+        self._initIndexes()
+        self._accounts()
 
+    def _initIndexes(self):
+        """
+        Create empty indexes
+        """
+        self.records = {}
+        self.recordIndexes = {}
+
+        for recordType in self.recordTypes():
+            self.records[recordType] = set()
+            self.recordIndexes[recordType] = {
+                self.INDEX_TYPE_GUID     : {},
+                self.INDEX_TYPE_SHORTNAME: {},
+                self.INDEX_TYPE_CUA      : {},
+                self.INDEX_TYPE_AUTHID   : {},
+            }
+
+    def _accounts(self):
+        """
+        Parses XML file, creates XMLDirectoryRecords and indexes them, and
+        because some other code in this module still works directly with
+        XMLAccountRecords as returned by XMLAccountsParser, returns a list
+        of XMLAccountRecords.
+
+        The XML file is only stat'ed at most every 60 seconds, and is only
+        reparsed if it's been modified.
+
+        FIXME: don't return XMLAccountRecords, and have any code in this module
+        which currently does work with XMLAccountRecords, modify such code to
+        use XMLDirectoryRecords instead.
+        """
+        currentTime = time()
+        if self._alwaysStat or currentTime - self._lastCheck > 60:
+            self.xmlFile.restat()
+            self._lastCheck = currentTime
+            fileInfo = (self.xmlFile.getmtime(), self.xmlFile.getsize())
+            if fileInfo != self._fileInfo:
+                self._initIndexes()
+                parser = XMLAccountsParser(self.xmlFile)
+                self._parsedAccounts = parser.items
+                self.realmName = parser.realm
+                self._fileInfo = fileInfo
+
+                for accountDict in self._parsedAccounts.itervalues():
+                    for xmlAccountRecord in accountDict.itervalues():
+                        if xmlAccountRecord.recordType not in self.recordTypes():
+                            continue
+                        record = XMLDirectoryRecord(
+                            service       = self,
+                            recordType    = xmlAccountRecord.recordType,
+                            shortNames    = tuple(xmlAccountRecord.shortNames),
+                            xmlPrincipal  = xmlAccountRecord,
+                        )
+                        d = augment.AugmentService.getAugmentRecord(record.guid,
+                            record.recordType)
+                        d.addCallback(lambda x:record.addAugmentInformation(x))
+
+                        self._addToIndex(record)
+
+        return self._parsedAccounts
+
+    def _addToIndex(self, record):
+        """
+        Index the record by GUID, shortName(s), authID(s) and CUA(s)
+        """
+
+        self.recordIndexes[record.recordType][self.INDEX_TYPE_GUID][record.guid] = record
+        for shortName in record.shortNames:
+            self.recordIndexes[record.recordType][self.INDEX_TYPE_SHORTNAME][shortName] = record
+        for authID in record.authIDs:
+            self.recordIndexes[record.recordType][self.INDEX_TYPE_AUTHID][authID] = record
+        for cua in record.calendarUserAddresses:
+            cua = normalizeCUAddr(cua)
+            self.recordIndexes[record.recordType][self.INDEX_TYPE_CUA][cua] = record
+        self.records[record.recordType].add(record)
+
+    def _removeFromIndex(self, record):
+        """
+        Removes a record from all indexes.  Note this is only used for unit
+        testing, to simulate a user being removed from the directory.
+        """
+        del self.recordIndexes[record.recordType][self.INDEX_TYPE_GUID][record.guid]
+        for shortName in record.shortNames:
+            del self.recordIndexes[record.recordType][self.INDEX_TYPE_SHORTNAME][shortName]
+        for authID in record.authIDs:
+            del self.recordIndexes[record.recordType][self.INDEX_TYPE_AUTHID][authID]
+        for cua in record.calendarUserAddresses:
+            cua = normalizeCUAddr(cua)
+            del self.recordIndexes[record.recordType][self.INDEX_TYPE_CUA][cua] 
+        if record in self.records[record.recordType]:
+            self.records[record.recordType].remove(record)
+
+
+    def _lookupInIndex(self, recordType, indexType, key):
+        """
+        Look for an existing record of the given recordType with the key for
+        the given index type.  Returns None if no match.
+        """
         self._accounts()
+        return self.recordIndexes.get(recordType, {}).get(indexType, {}).get(key, None)
 
+    def _initCaches(self):
+        """
+        Invalidates the indexes
+        """
+        self._lastCheck = 0
+        self._initIndexes()
 
-    def createCache(self):
+    def _forceReload(self):
         """
-        No-op to pacify addressbook backing.
+        Invalidates the indexes, re-reads the XML file and re-indexes
         """
-        
+        self._initCaches()
+        self._fileInfo = None
+        return self._accounts()
 
-    def recordTypes(self):
-        return self._recordTypes
 
-    def listRecords(self, recordType):
-        self._lastCheck = 0
-        for xmlPrincipal in self._accounts()[recordType].itervalues():
-            record = self.recordWithGUID(xmlPrincipal.guid)
+    def recordWithCalendarUserAddress(self, cua):
+        cua = normalizeCUAddr(cua)
+        for recordType in self.recordTypes():
+            record = self._lookupInIndex(recordType, self.INDEX_TYPE_CUA, cua)
+            if record and record.enabledForCalendaring:
+                return record
+        return None
+
+    def recordWithShortName(self, recordType, shortName):
+        return self._lookupInIndex(recordType, self.INDEX_TYPE_SHORTNAME, shortName)
+
+    def recordWithAuthID(self, authID):
+        for recordType in self.recordTypes():
+            record = self._lookupInIndex(recordType, self.INDEX_TYPE_AUTHID, authID)
             if record is not None:
-                yield record
+                return record
+        return None
 
-    def queryDirectory(self, recordTypes, indexType, indexKey):
+    def recordWithGUID(self, guid):
+        for recordType in self.recordTypes():
+            record = self._lookupInIndex(recordType, self.INDEX_TYPE_GUID, guid)
+            if record is not None:
+                return record
+        return None
+
+    recordWithUID = recordWithGUID
+
+    def createCache(self):
         """
-        If the query is a miss, re-read from the XML file and try again
+        No-op to pacify addressbook backing.
         """
-        if not self._queryDirectory(recordTypes, indexType, indexKey):
-            self._lastCheck = 0
-            self._queryDirectory(recordTypes, indexType, indexKey)
 
-    def _queryDirectory(self, recordTypes, indexType, indexKey):
 
-        anyMatches = False
+    def recordTypes(self):
+        return self._recordTypes
 
-        for recordType in recordTypes:
-            for xmlPrincipal in self._accounts()[recordType].itervalues():
-                record = XMLDirectoryRecord(
-                    service       = self,
-                    recordType    = recordType,
-                    shortNames    = tuple(xmlPrincipal.shortNames),
-                    xmlPrincipal  = xmlPrincipal,
-                )
+    def listRecords(self, recordType):
+        self._accounts()
+        return self.records[recordType]
 
-                # Look up augment information
-                # TODO: this needs to be deferred but for now we hard code the deferred result because
-                # we know it is completing immediately.
-                d = augment.AugmentService.getAugmentRecord(record.guid,
-                    recordType)
-                d.addCallback(lambda x:record.addAugmentInformation(x))
 
-                matched = False
-                if indexType == self.INDEX_TYPE_GUID:
-                    matched = indexKey == record.guid
-                elif indexType == self.INDEX_TYPE_SHORTNAME:
-                    matched = indexKey in record.shortNames
-                elif indexType == self.INDEX_TYPE_CUA:
-                    matched = indexKey in record.calendarUserAddresses
-                
-                if matched:
-                    anyMatches = True
-                    self.recordCacheForType(recordType).addRecord(record, indexType, indexKey)
-
-        return anyMatches
-            
     def recordsMatchingFields(self, fields, operand="or", recordType=None):
         # Default, brute force method search of underlying XML data
 
@@ -178,12 +282,12 @@
                 return False
             elif type(fieldValue) in types.StringTypes:
                 fieldValue = (fieldValue,)
-            
+
             for testValue in fieldValue:
                 if caseless:
                     testValue = testValue.lower()
                     value = value.lower()
-    
+
                 if matchType == 'starts-with':
                     if testValue.startswith(value):
                         return True
@@ -196,7 +300,7 @@
                 else: # exact
                     if testValue == value:
                         return True
-                    
+
             return False
 
         def xmlPrincipalMatches(xmlPrincipal):
@@ -231,30 +335,13 @@
         for recordType in recordTypes:
             for xmlPrincipal in self._accounts()[recordType].itervalues():
                 if xmlPrincipalMatches(xmlPrincipal):
-                    
+
                     # Load/cache record from its GUID
                     record = self.recordWithGUID(xmlPrincipal.guid)
                     if record:
                         yield record
 
-    def _initCaches(self):
-        super(XMLDirectoryService, self)._initCaches()
-        self._lastCheck = 0
 
-    def _accounts(self):
-        currentTime = time()
-        if self._alwaysStat or currentTime - self._lastCheck > 60:
-            self.xmlFile.restat()
-            self._lastCheck = currentTime
-            fileInfo = (self.xmlFile.getmtime(), self.xmlFile.getsize())
-            if fileInfo != self._fileInfo:
-                parser = XMLAccountsParser(self.xmlFile)
-                self._parsedAccounts = parser.items
-                self.realmName = parser.realm
-                self._fileInfo = fileInfo
-        return self._parsedAccounts
-
-
     def _addElement(self, parent, principal):
         """
         Create an XML element from principal and add it as a child of parent
@@ -307,13 +394,7 @@
 
         self.xmlFile.setContent(ET.tostring(element))
 
-        # Reload
-        self._initCaches() # nuke local cache
-        self._lastCheck = 0
-        self._accounts()
-        # TODO: nuke memcache entries, or prepopulate them
 
-
     def createRecord(self, recordType, guid=None, shortNames=(), authIDs=set(),
         fullName=None, firstName=None, lastName=None, emailAddresses=set(),
         uid=None, password=None, **kwargs):
@@ -330,8 +411,7 @@
             shortNames = (guid,)
 
         # Make sure latest XML records are read in
-        self._lastCheck = 0
-        accounts = self._accounts()
+        accounts = self._forceReload()
 
         accountsElement = ET.Element("accounts", realm=self.realmName)
         for recType in self.recordTypes():
@@ -356,7 +436,7 @@
         self._addElement(accountsElement, xmlPrincipal)
 
         self._persistRecords(accountsElement)
-
+        self._forceReload()
         return self.recordWithGUID(guid)
 
 
@@ -369,8 +449,7 @@
         """
 
         # Make sure latest XML records are read in
-        self._lastCheck = 0
-        accounts = self._accounts()
+        accounts = self._forceReload()
 
         accountsElement = ET.Element("accounts", realm=self.realmName)
         for recType in self.recordTypes():
@@ -380,6 +459,7 @@
                     self._addElement(accountsElement, xmlPrincipal)
 
         self._persistRecords(accountsElement)
+        self._forceReload()
 
 
     def updateRecord(self, recordType, guid=None, shortNames=(), authIDs=set(),
@@ -393,8 +473,7 @@
         """
 
         # Make sure latest XML records are read in
-        self._lastCheck = 0
-        accounts = self._accounts()
+        accounts = self._forceReload()
 
         accountsElement = ET.Element("accounts", realm=self.realmName)
         for recType in self.recordTypes():
@@ -414,12 +493,7 @@
                     self._addElement(accountsElement, xmlPrincipal)
 
         self._persistRecords(accountsElement)
-
-        # Force a cache update - both local and memcached
-        self.queryDirectory([recordType], self.INDEX_TYPE_GUID, guid)
-        for shortName in shortNames:
-            self.queryDirectory([recordType], self.INDEX_TYPE_SHORTNAME, shortName)
-
+        self._forceReload()
         return self.recordWithGUID(guid)
 
     def createRecords(self, data):
@@ -428,8 +502,7 @@
         """
 
         # Make sure latest XML records are read in
-        self._lastCheck = 0
-        accounts = self._accounts()
+        accounts = self._forceReload()
 
         knownGUIDs = { }
         knownShortNames = { }
@@ -466,9 +539,10 @@
             self._addElement(accountsElement, xmlPrincipal)
 
         self._persistRecords(accountsElement)
+        self._forceReload()
 
 
-class XMLDirectoryRecord(CachingDirectoryRecord):
+class XMLDirectoryRecord(DirectoryRecord):
     """
     XML based implementation implementation of L{IDirectoryRecord}.
     """

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2010-09-11 02:06:55 UTC (rev 6280)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2010-09-13 18:16:50 UTC (rev 6281)
@@ -42,7 +42,6 @@
 DEFAULT_SERVICE_PARAMS = {
     "twistedcaldav.directory.xmlfile.XMLDirectoryService": {
         "xmlFile": "accounts.xml",
-        "cacheTimeout": 30,
         "recordTypes": ("users", "groups"),
     },
     "twistedcaldav.directory.appleopendirectory.OpenDirectoryService": {
@@ -57,7 +56,6 @@
 DEFAULT_RESOURCE_PARAMS = {
     "twistedcaldav.directory.xmlfile.XMLDirectoryService": {
         "xmlFile": "resources.xml",
-        "cacheTimeout": 1,
         "recordTypes" : ("locations", "resources"),
     },
 }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100913/bd66e1ed/attachment-0001.html>


More information about the calendarserver-changes mailing list