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

source_changes at macosforge.org source_changes at macosforge.org
Fri Aug 26 13:36:20 PDT 2011


Revision: 8031
          http://trac.macosforge.org/projects/calendarserver/changeset/8031
Author:   sagen at apple.com
Date:     2011-08-26 13:36:19 -0700 (Fri, 26 Aug 2011)
Log Message:
-----------
Adds some optimizations to cut down on number of LDAP requests made

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py
    CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py
    CalendarServer/trunk/twistedcaldav/stdconfig.py

Modified: CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py	2011-08-26 20:29:55 UTC (rev 8030)
+++ CalendarServer/trunk/twistedcaldav/directory/ldapdirectory.py	2011-08-26 20:36:19 UTC (rev 8031)
@@ -81,6 +81,8 @@
             "groupMembershipCache" : None,
             "cacheTimeout": 1, # Minutes
             "negativeCaching": False,
+            "warningThresholdSeconds": 3,
+            "queryLocationsImplicitly": True,
             "restrictEnabledRecords": False,
             "restrictToGroup": "",
             "recordTypes": ("users", "groups"),
@@ -187,6 +189,8 @@
         super(LdapDirectoryService, self).__init__(params["cacheTimeout"],
                                                    params["negativeCaching"])
 
+        self.warningThresholdSeconds = params["warningThresholdSeconds"]
+        self.queryLocationsImplicitly = params["queryLocationsImplicitly"]
         self.augmentService = params["augmentService"]
         self.groupMembershipCache = params["groupMembershipCache"]
         self.realmName = params["uri"]
@@ -292,7 +296,11 @@
         self.log_debug("Querying ldap for records matching base %s and filter %s for attributes %s." %
             (ldap.dn.dn2str(base), filter, self.attrList))
 
-        results = self.ldap.search_s(ldap.dn.dn2str(base),
+        # This takes a while, so if you don't want to have a "long request"
+        # warning logged, use this instead of timedSearch:
+        # results = self.ldap.search_s(ldap.dn.dn2str(base),
+        #     ldap.SCOPE_SUBTREE, filter, self.attrList)
+        results = self.timedSearch(ldap.dn.dn2str(base),
             ldap.SCOPE_SUBTREE, filter, self.attrList)
 
         records = []
@@ -394,6 +402,20 @@
         self.log_debug("Authentication succeeded for %s" % (dn,))
 
 
+    def timedSearch(self, *args, **kwds):
+        """
+        Execute an ldap.search_s( ); if it takes longer than the configured
+        threshold, emit a log error.
+        """
+        startTime = time.time()
+        result = self.ldap.search_s(*args, **kwds)
+        totalTime = time.time() - startTime
+        if totalTime > self.warningThresholdSeconds:
+            self.log_error("LDAP query exceeded threshold: %.2f seconds for %s %s (#results=%d)" %
+                (totalTime, args, kwds, len(result)))
+        return result
+
+
     @property
     def restrictedGUIDs(self):
         """
@@ -465,7 +487,7 @@
 
             self.log_debug("Retrieving ldap record with base %s and filter %s." %
                 (ldap.dn.dn2str(base), filter))
-            result = self.ldap.search_s(ldap.dn.dn2str(base),
+            result = self.timedSearch(ldap.dn.dn2str(base),
                 ldap.SCOPE_SUBTREE, filter, self.attrList)
 
             if len(result) == 0:
@@ -759,7 +781,7 @@
             # Query the LDAP server
             self.log_debug("Retrieving ldap record with base %s and filter %s." %
                 (ldap.dn.dn2str(base), filter))
-            result = self.ldap.search_s(ldap.dn.dn2str(base),
+            result = self.timedSearch(ldap.dn.dn2str(base),
                 ldap.SCOPE_SUBTREE, filter, self.attrList)
 
             if result:
@@ -787,6 +809,9 @@
 
                     record.applySACLs()
 
+                    # We got a match, so don't bother checking other types
+                    break
+
                 except MissingGuidException:
                     self.log_warn("Ignoring record missing guid attribute: recordType %s, indexType %s and indexKey %s"
                         % (recordTypes, indexType, indexKey))
@@ -799,7 +824,20 @@
         records = []
 
         self.log_debug("Peforming principal property search for %s" % (fields,))
-        recordTypes = [recordType] if recordType else self.recordTypes()
+
+        if recordType is None:
+            recordTypes = self.recordTypes()
+            # principal-property-search syntax doesn't provide a way to ask
+            # for 3 of the 4 types (either all types or a single type).  This
+            # is wasteful in the case of iCal looking for event attendees
+            # since it always ignores the locations.  This config flag lets
+            # you skip querying for locations in this case:
+            if not self.queryLocationsImplicitly:
+                if self.recordType_locations in recordTypes:
+                    recordTypes.remove(self.recordType_locations)
+        else:
+            recordTypes = [recordType]
+
         guidAttr = self.rdnSchema["guidAttr"]
         for recordType in recordTypes:
             filter = buildFilter(self.rdnSchema[recordType]["mapping"], fields,
@@ -811,10 +849,9 @@
 
                 self.log_debug("LDAP search %s %s" %
                     (ldap.dn.dn2str(base), filter))
-                results = self.ldap.search_s(ldap.dn.dn2str(base),
+                results = self.timedSearch(ldap.dn.dn2str(base),
                     ldap.SCOPE_SUBTREE, filter, self.attrList)
                 self.log_debug("LDAP search returned %d results" % (len(results),))
-
                 numMissingGuids = 0
                 for dn, attrs in results:
                     # Skip if group restriction is in place and guid is not
@@ -957,13 +994,13 @@
                     self.log_debug("Retrieving subtree of %s with filter %s" %
                         (ldap.dn.dn2str(base), filter),
                         system="LdapDirectoryService")
-                    result = self.service.ldap.search_s(ldap.dn.dn2str(base),
+                    result = self.service.timedSearch(ldap.dn.dn2str(base),
                         ldap.SCOPE_SUBTREE, filter, self.service.attrList)
 
                 else:
                     self.log_debug("Retrieving %s." % memberId,
                         system="LdapDirectoryService")
-                    result = self.service.ldap.search_s(memberId,
+                    result = self.service.timedSearch(memberId,
                         ldap.SCOPE_BASE, attrlist=self.service.attrList)
 
                 if result:
@@ -1022,7 +1059,7 @@
         groups = []
 
         try:
-            results = self.service.ldap.search_s(ldap.dn.dn2str(base),
+            results = self.service.timedSearch(ldap.dn.dn2str(base),
                 ldap.SCOPE_SUBTREE, filter, self.service.attrList)
 
             for dn, attrs in results:

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py	2011-08-26 20:29:55 UTC (rev 8030)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_ldapdirectory.py	2011-08-26 20:36:19 UTC (rev 8031)
@@ -120,6 +120,8 @@
                 "groupMembershipCache" : None,
                 "cacheTimeout": 1, # Minutes
                 "negativeCaching": False,
+                "warningThresholdSeconds": 3,
+                "queryLocationsImplicitly": True,
                 "restrictEnabledRecords": False,
                 "restrictToGroup": "",
                 "recordTypes": ("users", "groups", "locations", "resources"),

Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py	2011-08-26 20:29:55 UTC (rev 8030)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py	2011-08-26 20:36:19 UTC (rev 8031)
@@ -57,6 +57,8 @@
     "twistedcaldav.directory.ldapdirectory.LdapDirectoryService": {
         "cacheTimeout": 1, # Minutes
         "negativeCaching": False,
+        "warningThresholdSeconds": 3,
+        "queryLocationsImplicitly": True,
         "restrictEnabledRecords": False,
         "restrictToGroup": "",
         "recordTypes": ("users", "groups"),
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110826/ca041da6/attachment-0001.html>


More information about the calendarserver-changes mailing list