[CalendarServer-changes] [1659]
CalendarServer/branches/users/cdaboo/digestdb-fix-1654/twistedcaldav
/directory/digest.py
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jul 12 12:31:02 PDT 2007
Revision: 1659
http://trac.macosforge.org/projects/calendarserver/changeset/1659
Author: cdaboo at apple.com
Date: 2007-07-12 12:31:02 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
Attempting to alleviate lock contention issues:
- Make more efficient use of the database by using auto-commit mode.
- Use faster connection.execute() calls.
- Provide a connection reset option when more than a set number of failures occur one after the other.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/digestdb-fix-1654/twistedcaldav/directory/digest.py
Modified: CalendarServer/branches/users/cdaboo/digestdb-fix-1654/twistedcaldav/directory/digest.py
===================================================================
--- CalendarServer/branches/users/cdaboo/digestdb-fix-1654/twistedcaldav/directory/digest.py 2007-07-12 19:25:22 UTC (rev 1658)
+++ CalendarServer/branches/users/cdaboo/digestdb-fix-1654/twistedcaldav/directory/digest.py 2007-07-12 19:31:02 UTC (rev 1659)
@@ -18,16 +18,22 @@
from twistedcaldav.sql import AbstractSQLDatabase
+from twisted.cred import error
+from twisted.python import log
from twisted.web2.auth.digest import DigestCredentialFactory
+from twisted.web2.auth.digest import DigestedCredentials
from zope.interface import implements, Interface
import cPickle as pickle
-from twisted.cred import error
-from twisted.web2.auth.digest import DigestedCredentials
+import os
import time
-import os
+try:
+ from sqlite3 import OperationalError
+except ImportError:
+ from pysqlite2.dbapi2 import OperationalError
+
"""
Overrides twisted.web2.auth.digest to allow specifying a qop value as a configuration parameter.
Also adds an sqlite-based credentials cache that is multi-process safe.
@@ -151,76 +157,117 @@
dbFilename = ".db.digestcredentialscache"
dbFormatVersion = "2"
+ exceptionLimit = 10
+
def __init__(self, path):
db_path = os.path.join(path, DigestCredentialsDB.dbFilename)
if os.path.exists(db_path):
os.remove(db_path)
- super(DigestCredentialsDB, self).__init__(db_path)
- self.db = {}
+ super(DigestCredentialsDB, self).__init__(db_path, autocommit=True)
+ self.exceptions = 0
def has_key(self, key):
"""
See IDigestCredentialsDatabase.
"""
- for ignore_key in self._db_execute(
- "select KEY from DIGESTCREDENTIALS where KEY = :1",
- key
- ):
- return True
- else:
- return False
+ try:
+ for ignore_key in self._db_execute(
+ "select KEY from DIGESTCREDENTIALS where KEY = :1",
+ key
+ ):
+ return True
+ else:
+ return False
+ self.exceptions = 0
+ except OperationalError, e:
+ self.exceptions += 1
+ if self.exceptions >= self.exceptionLimit:
+ self._db_close()
+ log.err("Reset digest credentials database connection: %s" % (e,))
+ raise
def set(self, key, value):
"""
See IDigestCredentialsDatabase.
"""
- self._delete_from_db(key)
- pvalue = pickle.dumps(value)
- self._add_to_db(key, pvalue)
- self._db_commit()
+ try:
+ pvalue = pickle.dumps(value)
+ self._set_in_db(key, pvalue)
+ self.exceptions = 0
+ except OperationalError, e:
+ self.exceptions += 1
+ if self.exceptions >= self.exceptionLimit:
+ self._db_close()
+ log.err("Reset digest credentials database connection: %s" % (e,))
+ raise
def get(self, key):
"""
See IDigestCredentialsDatabase.
"""
- for pvalue in self._db_execute(
- "select VALUE from DIGESTCREDENTIALS where KEY = :1",
- key
- ):
- return pickle.loads(str(pvalue[0]))
- else:
- return None
+ try:
+ for pvalue in self._db_execute(
+ "select VALUE from DIGESTCREDENTIALS where KEY = :1",
+ key
+ ):
+ self.exceptions = 0
+ return pickle.loads(str(pvalue[0]))
+ else:
+ self.exceptions = 0
+ return None
+ except OperationalError, e:
+ self.exceptions += 1
+ if self.exceptions >= self.exceptionLimit:
+ self._db_close()
+ log.err("Reset digest credentials database connection: %s" % (e,))
+ raise
def delete(self, key):
"""
See IDigestCredentialsDatabase.
"""
- self._delete_from_db(key)
- self._db_commit()
+ try:
+ self._delete_from_db(key)
+ self.exceptions = 0
+ except OperationalError, e:
+ self.exceptions += 1
+ if self.exceptions >= self.exceptionLimit:
+ self._db_close()
+ log.err("Reset digest credentials database connection: %s" % (e,))
+ raise
def keys(self):
"""
See IDigestCredentialsDatabase.
"""
- result = []
- for key in self._db_execute("select KEY from DIGESTCREDENTIALS"):
- result.append(str(key[0]))
-
- return result
+ try:
+ result = []
+ for key in self._db_execute("select KEY from DIGESTCREDENTIALS"):
+ result.append(str(key[0]))
+
+ self.exceptions = 0
+ return result
+ except OperationalError, e:
+ self.exceptions += 1
+ if self.exceptions >= self.exceptionLimit:
+ self._db_close()
+ log.err("Reset digest credentials database connection: %s" % (e,))
+ raise
- def _add_to_db(self, key, value):
+ def _set_in_db(self, key, value):
"""
- Insert the specified entry into the database.
+ Insert the specified entry into the database, replacing any that might already exist.
@param key: the key to add.
@param value: the value to add.
"""
- self._db_execute(
+ self._db().execute(
"""
- insert into DIGESTCREDENTIALS (KEY, VALUE)
+ insert or replace into DIGESTCREDENTIALS (KEY, VALUE)
values (:1, :2)
- """, key, value
+ """, (key, value,)
)
+ self._db_commit()
def _delete_from_db(self, key):
"""
@@ -228,7 +275,8 @@
@param key: the key to remove.
"""
- self._db_execute("delete from DIGESTCREDENTIALS where KEY = :1", key)
+ self._db().execute("delete from DIGESTCREDENTIALS where KEY = :1", (key,))
+ self._db_commit()
def _db_version(self):
"""
@@ -254,7 +302,7 @@
q.execute(
"""
create table DIGESTCREDENTIALS (
- KEY text,
+ KEY text unique,
VALUE text
)
"""
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070712/114dbb52/attachment.html
More information about the calendarserver-changes
mailing list