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

source_changes at macosforge.org source_changes at macosforge.org
Wed Nov 12 11:34:41 PST 2008


Revision: 3373
          http://trac.macosforge.org/projects/calendarserver/changeset/3373
Author:   sagen at apple.com
Date:     2008-11-12 11:34:40 -0800 (Wed, 12 Nov 2008)
Log Message:
-----------
recordsMatchingFields( ) is now non-blocking, and the open directory flavor uses deferToThread

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/aggregate.py
    CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
    CalendarServer/trunk/twistedcaldav/directory/directory.py
    CalendarServer/trunk/twistedcaldav/directory/idirectory.py
    CalendarServer/trunk/twistedcaldav/extensions.py

Modified: CalendarServer/trunk/twistedcaldav/directory/aggregate.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/aggregate.py	2008-11-12 17:27:03 UTC (rev 3372)
+++ CalendarServer/trunk/twistedcaldav/directory/aggregate.py	2008-11-12 19:34:40 UTC (rev 3373)
@@ -24,11 +24,13 @@
     "DuplicateRecordTypeError",
 ]
 
+import itertools
 from twisted.cred.error import UnauthorizedLogin
 
 from twistedcaldav.directory.idirectory import IDirectoryService
 from twistedcaldav.directory.directory import DirectoryService, DirectoryError
 from twistedcaldav.directory.directory import UnknownRecordTypeError
+from twisted.internet.defer import inlineCallbacks, returnValue
 
 class AggregateDirectoryService(DirectoryService):
     """
@@ -103,17 +105,24 @@
     def recordWithCalendarUserAddress(self, address):
         return self._queryAll("recordWithCalendarUserAddress", address)
 
+    @inlineCallbacks
     def recordsMatchingFields(self, fields, operand="or", recordType=None):
+
         if recordType:
             services = (self.serviceForRecordType(recordType),)
         else:
             services = set(self._recordTypes.values())
 
+        generators = []
         for service in services:
-            for record in service.recordsMatchingFields(fields,
-                operand=operand, recordType=recordType):
-                    yield record
+            generator = (yield service.recordsMatchingFields(fields,
+                operand=operand, recordType=recordType))
+            generators.append(generator)
 
+        returnValue(itertools.chain(*generators))
+
+
+
     def serviceForRecordType(self, recordType):
         try:
             return self._recordTypes[recordType]

Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2008-11-12 17:27:03 UTC (rev 3372)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py	2008-11-12 19:34:40 UTC (rev 3373)
@@ -356,6 +356,19 @@
         # query, not per expression, so the current code uses whatever is
         # specified in the last field in the fields list
 
+        def collectResults(results):
+            self.log_info("Got back %d records from OD" % (len(results),))
+            for key, val in results.iteritems():
+                self.log_debug("OD result: %s %s" % (key, val))
+                try:
+                    guid = val[dsattributes.kDS1AttrGeneratedUID]
+                    record = self.recordWithGUID(guid)
+                    if record:
+                        yield record
+                except KeyError:
+                    pass
+
+
         operand = (dsquery.expression.OR if operand == "or"
             else dsquery.expression.AND)
 
@@ -375,32 +388,19 @@
         else:
             recordTypes = (self._toODRecordTypes[recordType],)
 
-        for recordType in recordTypes:
+        self.log_info("Calling OD: Types %s, Operand %s, Caseless %s, %s" % (recordTypes, operand, caseless, fields))
+        deferred = deferToThread(
+            opendirectory.queryRecordsWithAttributes,
+            self.directory,
+            dsquery.expression(operand, expressions).generate(),
+            caseless,
+            recordTypes,
+            [ dsattributes.kDS1AttrGeneratedUID ]
+        )
+        deferred.addCallback(collectResults)
+        return deferred
 
-            try:
-                self.log_info("Calling OD: Type %s, Operand %s, Caseless %s, %s" % (recordType, operand, caseless, fields))
-                results = opendirectory.queryRecordsWithAttributes(
-                    self.directory,
-                    dsquery.expression(operand, expressions).generate(),
-                    caseless,
-                    recordType,
-                    [ dsattributes.kDS1AttrGeneratedUID ]
-                )
-                self.log_info("Got back %d records from OD" % (len(results),))
-                for key, val in results.iteritems():
-                    self.log_debug("OD result: %s %s" % (key, val))
-                    try:
-                        guid = val[dsattributes.kDS1AttrGeneratedUID]
-                        rec = self.recordWithGUID(guid)
-                        if rec:
-                            yield rec
-                    except KeyError:
-                        pass
 
-            except Exception, e:
-                self.log_error("OD search failed: %s" % (e,))
-                raise
-
     def reloadCache(self, recordType, shortName=None, guid=None):
         if shortName:
             self.log_info("Faulting record %s into %s record cache" % (shortName, recordType))

Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py	2008-11-12 17:27:03 UTC (rev 3372)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py	2008-11-12 19:34:40 UTC (rev 3373)
@@ -34,6 +34,7 @@
 from twisted.cred.error import UnauthorizedLogin
 from twisted.cred.checkers import ICredentialsChecker
 from twisted.web2.dav.auth import IPrincipalCredentials
+from twisted.internet.defer import succeed
 
 from twistedcaldav.log import LoggingMixIn
 from twistedcaldav.directory.idirectory import IDirectoryService, IDirectoryRecord
@@ -196,21 +197,25 @@
                 # we didn't hit any
                 return False
 
-        try:
-            if recordType is None:
-                recordTypes = list(self.recordTypes())
-            else:
-                recordTypes = (recordType,)
+        def yieldMatches(recordType):
+            try:
+                if recordType is None:
+                    recordTypes = list(self.recordTypes())
+                else:
+                    recordTypes = (recordType,)
 
-            for recordType in recordTypes:
-                for record in self.listRecords(recordType):
-                    if recordMatches(record):
-                        yield record
-        except UnknownRecordTypeError:
-            # Skip this service since it doesn't understand this record type
-            pass
+                for recordType in recordTypes:
+                    for record in self.listRecords(recordType):
+                        if recordMatches(record):
+                            yield record
 
+            except UnknownRecordTypeError:
+                # Skip this service since it doesn't understand this record type
+                pass
 
+        return succeed(yieldMatches(recordType))
+
+
 class DirectoryRecord(LoggingMixIn):
     implements(IDirectoryRecord)
 

Modified: CalendarServer/trunk/twistedcaldav/directory/idirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/idirectory.py	2008-11-12 17:27:03 UTC (rev 3372)
+++ CalendarServer/trunk/twistedcaldav/directory/idirectory.py	2008-11-12 19:34:40 UTC (rev 3373)
@@ -74,7 +74,7 @@
 
     def recordsMatchingFields(fields):
         """
-        @return: a sequence of L{IDirectoryRecord}s which match the given
+        @return: a deferred sequence of L{IDirectoryRecord}s which match the given
             fields.
         """
 

Modified: CalendarServer/trunk/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/extensions.py	2008-11-12 17:27:03 UTC (rev 3372)
+++ CalendarServer/trunk/twistedcaldav/extensions.py	2008-11-12 19:34:40 UTC (rev 3373)
@@ -318,9 +318,12 @@
 
             if fields:
 
-                for record in dir.recordsMatchingFieldsWithCUType(fields,
-                    operand=operand, cuType=cuType):
+                d = waitForDeferred(dir.recordsMatchingFieldsWithCUType(fields,
+                    operand=operand, cuType=cuType))
+                yield d
+                records = d.getResult()
 
+                for record in records:
                     resource = principalCollection.principalForRecord(record)
 
                     # We've determined this is a matching resource
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081112/ca049e7f/attachment-0001.html>


More information about the calendarserver-changes mailing list