[CalendarServer-changes] [6113] CalendarServer/trunk/txcaldav/calendarstore/postgres.py
source_changes at macosforge.org
source_changes at macosforge.org
Wed Aug 18 11:43:51 PDT 2010
Revision: 6113
http://trac.macosforge.org/projects/calendarserver/changeset/6113
Author: cdaboo at apple.com
Date: 2010-08-18 11:43:51 -0700 (Wed, 18 Aug 2010)
Log Message:
-----------
Do proper UID reservation.
Modified Paths:
--------------
CalendarServer/trunk/txcaldav/calendarstore/postgres.py
Modified: CalendarServer/trunk/txcaldav/calendarstore/postgres.py
===================================================================
--- CalendarServer/trunk/txcaldav/calendarstore/postgres.py 2010-08-18 18:27:57 UTC (rev 6112)
+++ CalendarServer/trunk/txcaldav/calendarstore/postgres.py 2010-08-18 18:43:51 UTC (rev 6113)
@@ -71,10 +71,12 @@
from twext.python.log import Logger, LoggingMixIn
from twext.python.vcomponent import VComponent
+from twistedcaldav.config import config
from twistedcaldav.customxml import NotificationType
from twistedcaldav.dateops import normalizeForIndex
-from twistedcaldav.index import IndexedSearchException
+from twistedcaldav.index import IndexedSearchException, ReservationError
from twistedcaldav.instance import InvalidOverriddenInstanceError
+from twistedcaldav.memcachepool import CachePoolUserMixIn
from twistedcaldav.notifications import NotificationRecord
from twistedcaldav.query import calendarqueryfilter, calendarquery
from twistedcaldav.query.sqlgenerator import sqlgenerator
@@ -1054,30 +1056,171 @@
L{twistedcaldv.index.IndexSchedule}.
"""
+ class MemcachedUIDReserver(CachePoolUserMixIn, LoggingMixIn):
+ def __init__(self, index, cachePool=None):
+ self.index = index
+ self._cachePool = cachePool
+
+ def _key(self, uid):
+ return 'reservation:%s' % (
+ hashlib.md5('%s:%s' % (uid,
+ self.index.calendar._resourceID)).hexdigest())
+
+ def reserveUID(self, uid):
+ uid = uid.encode('utf-8')
+ self.log_debug("Reserving UID %r @ %r" % (
+ uid,
+ self.index.calendar))
+
+ def _handleFalse(result):
+ if result is False:
+ raise ReservationError(
+ "UID %s already reserved for calendar collection %s."
+ % (uid, self.index.calendar._name)
+ )
+
+ d = self.getCachePool().add(self._key(uid),
+ 'reserved',
+ expireTime=config.UIDReservationTimeOut)
+ d.addCallback(_handleFalse)
+ return d
+
+
+ def unreserveUID(self, uid):
+ uid = uid.encode('utf-8')
+ self.log_debug("Unreserving UID %r @ %r" % (
+ uid,
+ self.index.calendar))
+
+ def _handleFalse(result):
+ if result is False:
+ raise ReservationError(
+ "UID %s is not reserved for calendar collection %s."
+ % (uid, self.index.calendar._resourceID)
+ )
+
+ d =self.getCachePool().delete(self._key(uid))
+ d.addCallback(_handleFalse)
+ return d
+
+
+ def isReservedUID(self, uid):
+ uid = uid.encode('utf-8')
+ self.log_debug("Is reserved UID %r @ %r" % (
+ uid,
+ self.index.calendar))
+
+ def _checkValue((flags, value)):
+ if value is None:
+ return False
+ else:
+ return True
+
+ d = self.getCachePool().get(self._key(uid))
+ d.addCallback(_checkValue)
+ return d
+
+ class DummyUIDReserver(LoggingMixIn):
+
+ def __init__(self, index):
+ self.index = index
+ self.reservations = set()
+
+ def _key(self, uid):
+ return 'reservation:%s' % (
+ hashlib.md5('%s:%s' % (uid,
+ self.index.calendar._resourceID)).hexdigest())
+
+ def reserveUID(self, uid):
+ uid = uid.encode('utf-8')
+ self.log_debug("Reserving UID %r @ %r" % (
+ uid,
+ self.index.calendar))
+
+ key = self._key(uid)
+ if key in self.reservations:
+ raise ReservationError(
+ "UID %s already reserved for calendar collection %s."
+ % (uid, self.index.calendar._name)
+ )
+ self.reservations.add(key)
+ return succeed(None)
+
+
+ def unreserveUID(self, uid):
+ uid = uid.encode('utf-8')
+ self.log_debug("Unreserving UID %r @ %r" % (
+ uid,
+ self.index.calendar))
+
+ key = self._key(uid)
+ if key in self.reservations:
+ self.reservations.remove(key)
+ return succeed(None)
+
+
+ def isReservedUID(self, uid):
+ uid = uid.encode('utf-8')
+ self.log_debug("Is reserved UID %r @ %r" % (
+ uid,
+ self.index.calendar))
+ key = self._key(uid)
+ return succeed(key in self.reservations)
+
def __init__(self, calendar):
self.calendar = calendar
+ if (
+ hasattr(config, "Memcached") and
+ config.Memcached.Pools.Default.ClientEnabled
+ ):
+ self.reserver = PostgresLegacyIndexEmulator.MemcachedUIDReserver(self)
+ else:
+ # This is only used with unit tests
+ self.reserver = PostgresLegacyIndexEmulator.DummyUIDReserver(self)
-
@property
def _txn(self):
return self.calendar._txn
def reserveUID(self, uid):
- return succeed(None)
+ if self.calendar._name == "inbox":
+ return succeed(None)
+ else:
+ return self.reserver.reserveUID(uid)
def unreserveUID(self, uid):
- return succeed(None)
+ if self.calendar._name == "inbox":
+ return succeed(None)
+ else:
+ return self.reserver.unreserveUID(uid)
+ def isReservedUID(self, uid):
+ if self.calendar._name == "inbox":
+ return succeed(False)
+ else:
+ return self.reserver.isReservedUID(uid)
+
+
def isAllowedUID(self, uid, *names):
"""
- @see: L{twistedcaldav.index.Index.isAllowedUID}
+ Checks to see whether to allow an operation which would add the
+ specified UID to the index. Specifically, the operation may not
+ violate the constraint that UIDs must be unique.
+ @param uid: the UID to check
+ @param names: the names of resources being replaced or deleted by the
+ operation; UIDs associated with these resources are not checked.
+ @return: True if the UID is not in the index and is not reserved,
+ False otherwise.
"""
- return True
+ if self.calendar._name == "inbox":
+ return True
+ else:
+ rname = self.resourceNameForUID(uid)
+ return (rname is None or rname in names)
-
def resourceUIDForName(self, name):
obj = self.calendar.calendarObjectWithName(name)
if obj is None:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100818/e4e205fe/attachment-0001.html>
More information about the calendarserver-changes
mailing list