[CalendarServer-changes] [2503] CalendarServer/trunk/twistedcaldav/directory
source_changes at macosforge.org
source_changes at macosforge.org
Mon May 26 09:20:13 PDT 2008
Revision: 2503
http://trac.macosforge.org/projects/calendarserver/changeset/2503
Author: cdaboo at apple.com
Date: 2008-05-26 09:20:13 -0700 (Mon, 26 May 2008)
Log Message:
-----------
Handle the new generic Memcacher logic. Use inlineCallbacks. Fix the case where a user is removed from a group.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py
CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py
Modified: CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py 2008-05-26 16:18:19 UTC (rev 2502)
+++ CalendarServer/trunk/twistedcaldav/directory/calendaruserproxy.py 2008-05-26 16:20:13 UTC (rev 2503)
@@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-from twistedcaldav.memcacher import Memcacher
-from twisted.internet.defer import returnValue
"""
Implements a calendar user proxy principal.
@@ -24,9 +22,8 @@
"CalendarUserProxyPrincipalResource",
]
+from twisted.internet.defer import returnValue
from twisted.internet.defer import succeed, inlineCallbacks
-from twisted.internet.defer import deferredGenerator
-from twisted.internet.defer import waitForDeferred
from twisted.web2 import responsecode
from twisted.web2.dav import davxml
from twisted.web2.dav.element.base import dav_namespace
@@ -36,6 +33,7 @@
from twistedcaldav.config import config
from twistedcaldav.extensions import DAVFile, DAVPrincipalResource
from twistedcaldav.extensions import ReadOnlyWritePropertiesResourceMixIn
+from twistedcaldav.memcacher import Memcacher
from twistedcaldav.resource import CalDAVComplianceMixIn
from twistedcaldav.sql import AbstractSQLDatabase
from twistedcaldav.sql import db_prefix
@@ -184,13 +182,13 @@
"Attempt to use a non-existent principal %s as a group member of %s." % (uri, self.principalURL(),)
))
principals.append(principal)
- changed = yield principal.cacheNotifier.changed()
+ yield principal.cacheNotifier.changed()
# Map the principals to UIDs.
uids = [p.principalUID() for p in principals]
yield self._index().setGroupMembers(self.uid, uids)
- changed = yield self.parent.cacheNotifier.changed()
+ yield self.parent.cacheNotifier.changed()
returnValue(True)
##
@@ -271,7 +269,7 @@
def principalCollections(self):
return self.parent.principalCollections()
- @deferredGenerator
+ @inlineCallbacks
def _expandMemberUIDs(self, uid=None, relatives=None, uids=None):
if uid is None:
uid = self.principalUID()
@@ -285,48 +283,38 @@
uids.add(uid)
principal = self.parent.parent.principalForUID(uid)
if isinstance(principal, CalendarUserProxyPrincipalResource):
- d = waitForDeferred(self._directGroupMembers())
- yield d
- members = d.getResult()
+ members = yield self._directGroupMembers()
for member in members:
if member.principalUID() not in uids:
relatives.add(member)
- d = waitForDeferred(self._expandMemberUIDs(member.principalUID(), relatives, uids))
- yield d
- d.getResult()
+ yield self._expandMemberUIDs(member.principalUID(), relatives, uids)
elif isinstance(principal, DirectoryPrincipalResource):
- d = waitForDeferred(principal.groupMembers())
- yield d
- members = d.getResult()
+ members = yield principal.groupMembers()
relatives.update(members)
- yield relatives
+ returnValue(relatives)
- @deferredGenerator
+ @inlineCallbacks
def _directGroupMembers(self):
if self.hasEditableMembership():
# Get member UIDs from database and map to principal resources
- d = waitForDeferred(self._index().getMembers(self.uid))
- yield d
- members = d.getResult()
- yield [p for p in [self.pcollection.principalForUID(uid) for uid in members] if p]
+ members = yield self._index().getMembers(self.uid)
+ returnValue([p for p in [self.pcollection.principalForUID(uid) for uid in members] if p])
else:
# Fixed proxies
if self.proxyType == "calendar-proxy-write":
- yield self.parent.proxies()
+ returnValue(self.parent.proxies())
else:
- yield self.parent.readOnlyProxies()
+ returnValue(self.parent.readOnlyProxies())
def groupMembers(self):
return self._expandMemberUIDs()
- @deferredGenerator
+ @inlineCallbacks
def groupMemberships(self):
# Get membership UIDs and map to principal resources
- d = waitForDeferred(self._index().getMemberships(self.uid))
- yield d
- memberships = d.getResult()
- yield [p for p in [self.pcollection.principalForUID(uid) for uid in memberships] if p]
+ memberships = yield self._index().getMemberships(self.uid)
+ returnValue([p for p in [self.pcollection.principalForUID(uid) for uid in memberships] if p])
def hasEditableMembership(self):
return self.parent.hasEditableProxyMembership()
@@ -389,8 +377,7 @@
path = os.path.join(path, CalendarUserProxyDatabase.dbFilename)
super(CalendarUserProxyDatabase, self).__init__(path, True)
- if config.Memcached['ClientEnabled']:
- self._memcacher = CalendarUserProxyDatabase.ProxyDBMemcacher("proxyDB")
+ self._memcacher = CalendarUserProxyDatabase.ProxyDBMemcacher("proxyDB")
@inlineCallbacks
def setGroupMembers(self, principalUID, members):
@@ -401,24 +388,25 @@
@param members: a list UIDs of principals that are members of this group.
"""
+ # Get current members before we change them
+ current_members = yield self.getMembers(principalUID)
+ if current_members is None:
+ current_members = ()
+ current_members = set(current_members)
+
# Remove what is there, then add it back.
self._delete_from_db(principalUID)
self._add_to_db(principalUID, members)
self._db_commit()
- # Update cache if present
- if config.Memcached['ClientEnabled']:
- current_members = yield self.getMembers(principalUID)
- if current_members is None:
- current_members = ()
- current_members = set(current_members)
- update_members = set(members)
-
- remove_members = current_members.difference(update_members)
- add_members = update_members.difference(current_members)
- for member in itertools.chain(remove_members, add_members,):
- _ignore = yield self._memcacher.deleteMembership(member)
- _ignore = yield self._memcacher.deleteMember(principalUID)
+ # Update cache
+ update_members = set(members)
+
+ remove_members = current_members.difference(update_members)
+ add_members = update_members.difference(current_members)
+ for member in itertools.chain(remove_members, add_members,):
+ _ignore = yield self._memcacher.deleteMembership(member)
+ _ignore = yield self._memcacher.deleteMember(principalUID)
@inlineCallbacks
def removeGroup(self, principalUID):
@@ -431,13 +419,12 @@
self._delete_from_db(principalUID)
self._db_commit()
- # Update cache if present
- if config.Memcached['ClientEnabled']:
- members = yield self.getMembers(principalUID)
- if members:
- for member in members:
- _ignore = yield self._memcacher.deleteMembership(member)
- _ignore = yield self._memcacher.deleteMember(principalUID)
+ # Update cache
+ members = yield self.getMembers(principalUID)
+ if members:
+ for member in members:
+ yield self._memcacher.deleteMembership(member)
+ yield self._memcacher.deleteMember(principalUID)
@inlineCallbacks
def getMembers(self, principalUID):
@@ -453,15 +440,12 @@
members.add(row[0])
return members
- # Pull from cache if present
- if config.Memcached['ClientEnabled']:
- result = yield self._memcacher.getMembers(principalUID)
- if result is None:
- result = _members()
- _ignore = yield self._memcacher.setMembers(principalUID, result)
- returnValue(result)
- else:
- returnValue(_members())
+ # Pull from cache
+ result = yield self._memcacher.getMembers(principalUID)
+ if result is None:
+ result = _members()
+ yield self._memcacher.setMembers(principalUID, result)
+ returnValue(result)
@inlineCallbacks
def getMemberships(self, principalUID):
@@ -477,15 +461,12 @@
members.add(row[0])
return members
- # Pull from cache if present
- if config.Memcached['ClientEnabled']:
- result = yield self._memcacher.getMemberships(principalUID)
- if result is None:
- result = _members()
- _ignore = yield self._memcacher.setMemberships(principalUID, result)
- returnValue(result)
- else:
- returnValue(_members())
+ # Pull from cache
+ result = yield self._memcacher.getMemberships(principalUID)
+ if result is None:
+ result = _members()
+ yield self._memcacher.setMemberships(principalUID, result)
+ returnValue(result)
def _add_to_db(self, principalUID, members):
"""
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py 2008-05-26 16:18:19 UTC (rev 2502)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py 2008-05-26 16:20:13 UTC (rev 2503)
@@ -13,11 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from twistedcaldav.config import config
import os
-from twisted.internet.defer import deferredGenerator
-from twisted.internet.defer import waitForDeferred
+from twisted.internet.defer import inlineCallbacks
from twistedcaldav.directory.calendaruserproxy import CalendarUserProxyDatabase
import twistedcaldav.test.util
@@ -68,25 +68,18 @@
"""
return "51"
- @deferredGenerator
+ @inlineCallbacks
def test_normalDB(self):
# Get the DB
db_path = self.mktemp()
os.mkdir(db_path)
db = CalendarUserProxyDatabase(db_path)
- d = waitForDeferred(db.setGroupMembers("A", ("B", "C", "D",)))
- yield d
- d.getResult()
+ yield db.setGroupMembers("A", ("B", "C", "D",))
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
self.assertEqual(membersA, set(("B", "C", "D",)))
self.assertEqual(membershipsB, set(("A",)))
@@ -106,24 +99,18 @@
db = self.old_CalendarUserProxyDatabase(db_path)
self.assertEqual(set([row[1] for row in db._db_execute("PRAGMA index_list(GROUPS)")]), set())
+ @inlineCallbacks
def test_DBUpgrade(self):
# Get the DB
db_path = self.mktemp()
os.mkdir(db_path)
db = self.old_CalendarUserProxyDatabase(db_path)
- d = waitForDeferred(db.setGroupMembers("A", ("B", "C", "D",)))
- yield d
- d.getResult()
+ yield db.setGroupMembers("A", ("B", "C", "D",))
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
self.assertEqual(membersA, set(("B", "C", "D",)))
self.assertEqual(membershipsB, set(("A",)))
self.assertEqual(set([row[1] for row in db._db_execute("PRAGMA index_list(GROUPS)")]), set())
@@ -132,38 +119,27 @@
db = CalendarUserProxyDatabase(db_path)
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
self.assertEqual(membersA, set(("B", "C", "D",)))
self.assertEqual(membershipsB, set(("A",)))
self.assertEqual(set([row[1] for row in db._db_execute("PRAGMA index_list(GROUPS)")]), set(("GROUPNAMES", "MEMBERS")))
db._db_close()
db = None
+ @inlineCallbacks
def test_DBUpgradeNewer(self):
# Get the DB
db_path = self.mktemp()
os.mkdir(db_path)
db = self.old_CalendarUserProxyDatabase(db_path)
- d = waitForDeferred(db.setGroupMembers("A", ("B", "C", "D",)))
- yield d
- d.getResult()
+ yield db.setGroupMembers("A", ("B", "C", "D",))
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
self.assertEqual(membersA, set(("B", "C", "D",)))
self.assertEqual(membershipsB, set(("A",)))
self.assertEqual(set([row[1] for row in db._db_execute("PRAGMA index_list(GROUPS)")]), set())
@@ -172,38 +148,27 @@
db = self.new_CalendarUserProxyDatabase(db_path)
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
self.assertEqual(membersA, set(("B", "C", "D",)))
self.assertEqual(membershipsB, set(("A",)))
self.assertEqual(set([row[1] for row in db._db_execute("PRAGMA index_list(GROUPS)")]), set(("GROUPNAMES", "MEMBERS")))
db._db_close()
db = None
+ @inlineCallbacks
def test_DBNoUpgradeNewer(self):
# Get the DB
db_path = self.mktemp()
os.mkdir(db_path)
db = self.new_CalendarUserProxyDatabase(db_path)
- d = waitForDeferred(db.setGroupMembers("A", ("B", "C", "D",)))
- yield d
- d.getResult()
+ yield db.setGroupMembers("A", ("B", "C", "D",))
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
self.assertEqual(membersA, set(("B", "C", "D",)))
self.assertEqual(membershipsB, set(("A",)))
self.assertEqual(set([row[1] for row in db._db_execute("PRAGMA index_list(GROUPS)")]), set(("GROUPNAMES", "MEMBERS")))
@@ -212,154 +177,125 @@
db = self.newer_CalendarUserProxyDatabase(db_path)
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
self.assertEqual(membersA, set(("B", "C", "D",)))
self.assertEqual(membershipsB, set(("A",)))
self.assertEqual(set([row[1] for row in db._db_execute("PRAGMA index_list(GROUPS)")]), set(("GROUPNAMES", "MEMBERS")))
db._db_close()
db = None
+ @inlineCallbacks
def test_cachingDBInsert(self):
- # Get the DB
- db_path = self.mktemp()
- os.mkdir(db_path)
- db = CalendarUserProxyDatabase(db_path)
-
- # Do one insert and check the result
- d = waitForDeferred(db.setGroupMembers("A", ("B", "C", "D",)))
- yield d
- d.getResult()
+ for processType in ("Single", "Combined",):
+ config.processType = processType
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ # Get the DB
+ db_path = self.mktemp()
+ os.mkdir(db_path)
+ db = CalendarUserProxyDatabase(db_path)
+
+ # Do one insert and check the result
+ yield db.setGroupMembers("A", ("B", "C", "D",))
+
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
+ membershipsC = yield db.getMemberships("C")
+ membershipsD = yield db.getMemberships("D")
+ membershipsE = yield db.getMemberships("E")
+
+ self.assertEqual(membersA, set(("B", "C", "D",)))
+ self.assertEqual(membershipsB, set(("A",)))
+ self.assertEqual(membershipsC, set(("A",)))
+ self.assertEqual(membershipsD, set(("A",)))
+ self.assertEqual(membershipsE, set(()))
+
+ # Change and check the result
+ yield db.setGroupMembers("A", ("B", "C", "E",))
+
+ membersA = yield db.getMembers("A")
+ membershipsB = yield db.getMemberships("B")
+ membershipsC = yield db.getMemberships("C")
+ membershipsD = yield db.getMemberships("D")
+ membershipsE = yield db.getMemberships("E")
+
+ self.assertEqual(membersA, set(("B", "C", "E",)))
+ self.assertEqual(membershipsB, set(("A",)))
+ self.assertEqual(membershipsC, set(("A",)))
+ self.assertEqual(membershipsD, set())
+ self.assertEqual(membershipsE, set(("A",)))
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
- d = waitForDeferred(db.getMemberships("C"))
- yield d
- membershipsC = d.getResult()
-
- d = waitForDeferred(db.getMemberships("D"))
- yield d
- membershipsD = d.getResult()
-
- d = waitForDeferred(db.getMemberships("E"))
- yield d
- membershipsE = d.getResult()
-
- self.assertEqual(membersA, set(("B", "C", "D",)))
- self.assertEqual(membershipsB, set(("A",)))
- self.assertEqual(membershipsC, set(("A",)))
- self.assertEqual(membershipsD, set(("A",)))
- self.assertEqual(membershipsE, set(()))
-
- # Change and check the result
- d = waitForDeferred(db.setGroupMembers("A", ("B", "C", "E",)))
- yield d
- d.getResult()
-
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
-
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
- d = waitForDeferred(db.getMemberships("C"))
- yield d
- membershipsC = d.getResult()
-
- d = waitForDeferred(db.getMemberships("D"))
- yield d
- membershipsD = d.getResult()
-
- d = waitForDeferred(db.getMemberships("E"))
- yield d
- membershipsE = d.getResult()
-
- self.assertEqual(db.membersA, set(("B", "C", "E",)))
- self.assertEqual(membershipsB, set(("A",)))
- self.assertEqual(membershipsC, set(("A",)))
- self.assertEqual(membershipsD, set())
- self.assertEqual(membershipsE, set(("A",)))
-
+ @inlineCallbacks
def test_cachingDBRemove(self):
- # Get the DB
- db_path = self.mktemp()
- os.mkdir(db_path)
- db = CalendarUserProxyDatabase(db_path)
-
- # Do one insert and check the result
- d = waitForDeferred(db.setGroupMembers("A", ("B", "C", "D",)))
- yield d
- d.getResult()
+ for processType in ("Single", "Combined",):
+ config.processType = processType
- d = waitForDeferred(db.setGroupMembers("X", ("B", "C",)))
- yield d
- d.getResult()
+ # Get the DB
+ db_path = self.mktemp()
+ os.mkdir(db_path)
+ db = CalendarUserProxyDatabase(db_path)
+
+ # Do one insert and check the result
+ yield db.setGroupMembers("A", ("B", "C", "D",))
+ yield db.setGroupMembers("X", ("B", "C",))
+
+ membersA = yield db.getMembers("A")
+ membersX = yield db.getMembers("X")
+ membershipsB = yield db.getMemberships("B")
+ membershipsC = yield db.getMemberships("C")
+ membershipsD = yield db.getMemberships("D")
+
+ self.assertEqual(membersA, set(("B", "C", "D",)))
+ self.assertEqual(membersX, set(("B", "C",)))
+ self.assertEqual(membershipsB, set(("A", "X",)))
+ self.assertEqual(membershipsC, set(("A", "X",)))
+ self.assertEqual(membershipsD, set(("A",)))
+
+ # Remove and check the result
+ yield db.removeGroup("A")
+
+ membersA = yield db.getMembers("A")
+ membersX = yield db.getMembers("X")
+ membershipsB = yield db.getMemberships("B")
+ membershipsC = yield db.getMemberships("C")
+ membershipsD = yield db.getMemberships("D")
+
+ self.assertEqual(membersA, set())
+ self.assertEqual(membersX, set(("B", "C",)))
+ self.assertEqual(membershipsB, set("X",))
+ self.assertEqual(membershipsC, set("X",))
+ self.assertEqual(membershipsD, set())
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
+ @inlineCallbacks
+ def test_cachingDBInsertUncached(self):
+
+ for processType in ("Single", "Combined",):
+ config.processType = processType
- d = waitForDeferred(db.getMembers("X"))
- yield d
- membersX = d.getResult()
+ # Get the DB
+ db_path = self.mktemp()
+ os.mkdir(db_path)
+ db = CalendarUserProxyDatabase(db_path)
+
+ # Do one insert and check the result for the one we will remove
+ yield db.setGroupMembers("AA", ("BB", "CC", "DD",))
+ yield db.getMemberships("DD")
+
+ # Change and check the result
+ yield db.setGroupMembers("AA", ("BB", "CC", "EE",))
+
+ membersAA = yield db.getMembers("AA")
+ membershipsBB = yield db.getMemberships("BB")
+ membershipsCC = yield db.getMemberships("CC")
+ membershipsDD = yield db.getMemberships("DD")
+ membershipsEE = yield db.getMemberships("EE")
+
+ self.assertEqual(membersAA, set(("BB", "CC", "EE",)))
+ self.assertEqual(membershipsBB, set(("AA",)))
+ self.assertEqual(membershipsCC, set(("AA",)))
+ self.assertEqual(membershipsDD, set())
+ self.assertEqual(membershipsEE, set(("AA",)))
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
- d = waitForDeferred(db.getMemberships("C"))
- yield d
- membershipsC = d.getResult()
-
- d = waitForDeferred(db.getMemberships("D"))
- yield d
- membershipsD = d.getResult()
-
- self.assertEqual(membersA, set(("B", "C", "D",)))
- self.assertEqual(membersX, set(("B", "C",)))
- self.assertEqual(membershipsB, set(("A", "X",)))
- self.assertEqual(membershipsC, set(("A", "X",)))
- self.assertEqual(membershipsD, set(("A",)))
-
- # Remove and check the result
- d = waitForDeferred(db.removeGroup("A"))
- yield d
- d.getResult()
-
- d = waitForDeferred(db.getMembers("A"))
- yield d
- membersA = d.getResult()
-
- d = waitForDeferred(db.getMemberships("B"))
- yield d
- membershipsB = d.getResult()
-
- d = waitForDeferred(db.getMemberships("C"))
- yield d
- membershipsC = d.getResult()
-
- d = waitForDeferred(db.getMemberships("D"))
- yield d
- membershipsD = d.getResult()
-
- self.assertEqual(membersA, set())
- self.assertEqual(membershipsB, set("X",))
- self.assertEqual(membershipsC, set("X",))
- self.assertEqual(membershipsD, set())
-
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080526/9bdee327/attachment-0001.htm
More information about the calendarserver-changes
mailing list