[CalendarServer-changes] [7316] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Apr 13 17:08:53 PDT 2011
Revision: 7316
http://trac.macosforge.org/projects/calendarserver/changeset/7316
Author: sagen at apple.com
Date: 2011-04-13 17:08:52 -0700 (Wed, 13 Apr 2011)
Log Message:
-----------
Adds call to recycleAutoreleasePool after calls to OpenDirectory.framework via PyObjC; also purges expired directory records from internal caches.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py
CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py
Modified: CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py
===================================================================
--- CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py 2011-04-13 18:58:40 UTC (rev 7315)
+++ CalendarServer/trunk/calendarserver/platform/darwin/od/opendirectory.py 2011-04-14 00:08:52 UTC (rev 7316)
@@ -215,37 +215,41 @@
attributeNames, encodings = attributeNamesFromList(attributes)
- tries = NUM_TRIES
- while tries:
- query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
- directory.node,
- recordType,
- None,
- MATCHANY,
- None,
- attributeNames,
- count,
- None)
+ try:
+ tries = NUM_TRIES
+ while tries:
+ query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
+ directory.node,
+ recordType,
+ None,
+ MATCHANY,
+ None,
+ attributeNames,
+ count,
+ None)
- if not error:
- records, error = query.resultsAllowingPartial_error_(False, None)
+ if not error:
+ records, error = query.resultsAllowingPartial_error_(False, None)
- if not error:
- for record in records:
- results.append(recordToResult(record, encodings))
- return results
+ if not error:
+ for record in records:
+ results.append(recordToResult(record, encodings))
+ return results
- code = error.code()
- log.debug("Received code %d from query call: %s" % (code, error))
+ code = error.code()
+ log.debug("Received code %d from query call: %s" % (code, error))
- if code in RETRY_CODES:
- tries -= 1
- else:
- break
+ if code in RETRY_CODES:
+ tries -= 1
+ else:
+ break
- log.error(error)
- raise ODError(error)
+ log.error(error)
+ raise ODError(error)
+ finally:
+ objc.recycleAutoreleasePool()
+
def queryRecordsWithAttribute_list(directory, attr, value, matchType, casei, recordType, attributes, count=0):
"""
List records in Open Directory matching specified attribute/value, and return key attributes for each one.
@@ -268,39 +272,43 @@
attributeNames, encodings = attributeNamesFromList(attributes)
- tries = NUM_TRIES
- while tries:
+ try:
+ tries = NUM_TRIES
+ while tries:
- query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
- directory.node,
- recordType,
- attr,
- adjustMatchType(matchType, casei),
- value.decode("utf-8"),
- attributeNames,
- count,
- None)
+ query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
+ directory.node,
+ recordType,
+ attr,
+ adjustMatchType(matchType, casei),
+ value.decode("utf-8"),
+ attributeNames,
+ count,
+ None)
- if not error:
- records, error = query.resultsAllowingPartial_error_(False, None)
+ if not error:
+ records, error = query.resultsAllowingPartial_error_(False, None)
- if not error:
- for record in records:
- results.append(recordToResult(record, encodings))
- return results
+ if not error:
+ for record in records:
+ results.append(recordToResult(record, encodings))
+ return results
- code = error.code()
- log.debug("Received code %d from query call: %s" % (code, error))
+ code = error.code()
+ log.debug("Received code %d from query call: %s" % (code, error))
- if code in RETRY_CODES:
- tries -= 1
- else:
- break
+ if code in RETRY_CODES:
+ tries -= 1
+ else:
+ break
- log.error(error)
- raise ODError(error)
+ log.error(error)
+ raise ODError(error)
+ finally:
+ objc.recycleAutoreleasePool()
+
def queryRecordsWithAttributes_list(directory, compound, casei, recordType, attributes, count=0):
"""
List records in Open Directory matching specified criteria, and return key attributes for each one.
@@ -320,39 +328,43 @@
attributeNames, encodings = attributeNamesFromList(attributes)
- tries = NUM_TRIES
- while tries:
+ try:
+ tries = NUM_TRIES
+ while tries:
- query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
- directory.node,
- recordType,
- None,
- 0x210B, # adjustMatchType(matchType, casei),
- compound,
- attributeNames,
- count,
- None)
+ query, error = odframework.ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
+ directory.node,
+ recordType,
+ None,
+ 0x210B, # adjustMatchType(matchType, casei),
+ compound,
+ attributeNames,
+ count,
+ None)
- if not error:
- records, error = query.resultsAllowingPartial_error_(False, None)
+ if not error:
+ records, error = query.resultsAllowingPartial_error_(False, None)
- if not error:
- for record in records:
- results.append(recordToResult(record, encodings))
- return results
+ if not error:
+ for record in records:
+ results.append(recordToResult(record, encodings))
+ return results
- code = error.code()
- log.debug("Received code %d from query call: %s" % (code, error))
+ code = error.code()
+ log.debug("Received code %d from query call: %s" % (code, error))
- if code in RETRY_CODES:
- tries -= 1
- else:
- break
+ if code in RETRY_CODES:
+ tries -= 1
+ else:
+ break
- log.error(error)
- raise ODError(error)
+ log.error(error)
+ raise ODError(error)
+ finally:
+ objc.recycleAutoreleasePool()
+
def getUserRecord(directory, user):
"""
Look up the record for the given user within the directory's node
@@ -395,39 +407,43 @@
@param pswd: C{str} containing the password to check.
@return: C{True} if the user was found, C{False} otherwise.
"""
- record = getUserRecord(directory, user)
- if record is None:
- raise ODError("Record not found")
+ try:
+ record = getUserRecord(directory, user)
+ if record is None:
+ raise ODError("Record not found")
- tries = NUM_TRIES
- while tries:
+ tries = NUM_TRIES
+ while tries:
- log.debug("Checking basic auth for user '%s' (tries remaining: %d)" %
- (user, tries))
+ log.debug("Checking basic auth for user '%s' (tries remaining: %d)" %
+ (user, tries))
- result, error = record.verifyPassword_error_(password, None)
- if not error:
- log.debug("Basic auth for user '%s' result: %s" % (user, result))
- return result
+ result, error = record.verifyPassword_error_(password, None)
+ if not error:
+ log.debug("Basic auth for user '%s' result: %s" % (user, result))
+ return result
- code = error.code()
+ code = error.code()
- if code == INCORRECT_CREDENTIALS:
- log.debug("Basic auth for user '%s' failed due to incorrect credentials" % (user,))
- return False
+ if code == INCORRECT_CREDENTIALS:
+ log.debug("Basic auth for user '%s' failed due to incorrect credentials" % (user,))
+ return False
- log.debug("Basic auth for user '%s' failed with code %d (%s)" %
- (user, code, error))
+ log.debug("Basic auth for user '%s' failed with code %d (%s)" %
+ (user, code, error))
- if code in RETRY_CODES:
- tries -= 1
- else:
- break
+ if code in RETRY_CODES:
+ tries -= 1
+ else:
+ break
- log.error(error)
- raise ODError(error)
+ log.error(error)
+ raise ODError(error)
+ finally:
+ objc.recycleAutoreleasePool()
+
def authenticateUserDigest(directory, nodeName, user, challenge, response, method):
"""
Authenticate using HTTP Digest credentials to Open Directory.
@@ -440,44 +456,48 @@
@param method: C{str} the HTTP method being used.
@return: C{True} if the user was found, C{False} otherwise.
"""
- record = getUserRecord(directory, user)
- if record is None:
- raise ODError("Record not found")
+ try:
+ record = getUserRecord(directory, user)
+ if record is None:
+ raise ODError("Record not found")
- tries = NUM_TRIES
- while tries:
+ tries = NUM_TRIES
+ while tries:
- log.debug("Checking digest auth for user '%s' (tries remaining: %d)" %
- (user, tries))
+ log.debug("Checking digest auth for user '%s' (tries remaining: %d)" %
+ (user, tries))
- # TODO: what are these other return values?
- result, mystery1, mystery2, error = record.verifyExtendedWithAuthenticationType_authenticationItems_continueItems_context_error_(
- DIGEST_MD5,
- [user, challenge, response, method],
- None, None, None
- )
- if not error:
- log.debug("Digest auth for user '%s' result: %s" % (user, result))
- return result
+ # TODO: what are these other return values?
+ result, mystery1, mystery2, error = record.verifyExtendedWithAuthenticationType_authenticationItems_continueItems_context_error_(
+ DIGEST_MD5,
+ [user, challenge, response, method],
+ None, None, None
+ )
+ if not error:
+ log.debug("Digest auth for user '%s' result: %s" % (user, result))
+ return result
- code = error.code()
+ code = error.code()
- if code == INCORRECT_CREDENTIALS:
- log.debug("Digest auth for user '%s' failed due to incorrect credentials" % (user,))
- return False
+ if code == INCORRECT_CREDENTIALS:
+ log.debug("Digest auth for user '%s' failed due to incorrect credentials" % (user,))
+ return False
- log.debug("Digest auth for user '%s' failed with code %d (%s)" %
- (user, code, error))
+ log.debug("Digest auth for user '%s' failed with code %d (%s)" %
+ (user, code, error))
- if code in RETRY_CODES:
- tries -= 1
- else:
- break
+ if code in RETRY_CODES:
+ tries -= 1
+ else:
+ break
- log.error(error)
- raise ODError(error)
+ log.error(error)
+ raise ODError(error)
+ finally:
+ objc.recycleAutoreleasePool()
+
class ODError(Exception):
"""
Exceptions from DirectoryServices errors.
Modified: CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py 2011-04-13 18:58:40 UTC (rev 7315)
+++ CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py 2011-04-14 00:08:52 UTC (rev 7316)
@@ -74,6 +74,7 @@
CachingDirectoryService.INDEX_TYPE_AUTHID : {},
}
self.directoryService = directoryService
+ self.lastPurgedTime = time.time()
def addRecord(self, record, indexType, indexKey, useMemcache=True,
neverExpire=False):
@@ -121,8 +122,22 @@
self.log_debug("Missing record index item; type: %s, item: %s" % (indexType, item))
def findRecord(self, indexType, indexKey):
+ self.purgeExpiredRecords()
return self.recordsIndexedBy[indexType].get(indexKey)
+
+ def purgeExpiredRecords(self):
+ """
+ Scan the cached records and remove any that have expired.
+ Does nothing if we've scanned within the past cacheTimeout seconds.
+ """
+ if time.time() - self.lastPurgedTime > self.directoryService.cacheTimeout:
+ for record in list(self.records):
+ if record.isExpired():
+ self.removeRecord(record)
+ self.lastPurgedTime = time.time()
+
+
class CachingDirectoryService(DirectoryService):
"""
Caching Directory implementation of L{IDirectoryService}.
@@ -272,10 +287,7 @@
record = self.recordCacheForType(recordType).findRecord(indexType, indexKey)
if record:
- if (
- record.cachedTime != 0 and
- time.time() - record.cachedTime > self.cacheTimeout
- ):
+ if record.isExpired():
self.recordCacheForType(recordType).removeRecord(record)
return None
else:
@@ -386,6 +398,20 @@
def neverExpire(self):
self.cachedTime = 0
+ def isExpired(self):
+ """
+ Returns True if this record was created more than cacheTimeout
+ seconds ago
+ """
+ if (
+ self.cachedTime != 0 and
+ time.time() - self.cachedTime > self.service.cacheTimeout
+ ):
+ return True
+ else:
+ return False
+
+
class DirectoryMemcacheError(DirectoryError):
"""
Error communicating with memcached.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110413/2de65bbe/attachment-0001.html>
More information about the calendarserver-changes
mailing list