[CalendarServer-changes] [9459] CalendarServer/trunk/txdav
source_changes at macosforge.org
source_changes at macosforge.org
Tue Jul 17 13:32:22 PDT 2012
Revision: 9459
http://trac.macosforge.org/projects/calendarserver/changeset/9459
Author: sagen at apple.com
Date: 2012-07-17 13:32:21 -0700 (Tue, 17 Jul 2012)
Log Message:
-----------
Send push notifications upon DAV property changes
Modified Paths:
--------------
CalendarServer/trunk/txdav/base/propertystore/sql.py
CalendarServer/trunk/txdav/caldav/datastore/test/common.py
CalendarServer/trunk/txdav/carddav/datastore/test/common.py
CalendarServer/trunk/txdav/common/datastore/file.py
CalendarServer/trunk/txdav/common/datastore/sql.py
Modified: CalendarServer/trunk/txdav/base/propertystore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/base/propertystore/sql.py 2012-07-17 00:20:24 UTC (rev 9458)
+++ CalendarServer/trunk/txdav/base/propertystore/sql.py 2012-07-17 20:32:21 UTC (rev 9459)
@@ -73,7 +73,11 @@
@classmethod
@inlineCallbacks
- def load(cls, defaultuser, txn, resourceID, created=False):
+ def load(cls, defaultuser, txn, resourceID, created=False, notifyCallback=None):
+ """
+ @param notifyCallback: a callable used to trigger notifications when the
+ property store changes.
+ """
self = cls.__new__(cls)
super(PropertyStore, self).__init__(defaultuser)
self._txn = txn
@@ -81,6 +85,7 @@
self._cached = {}
if not created:
yield self._refresh(txn)
+ self._notifyCallback = notifyCallback
returnValue(self)
@@ -196,6 +201,11 @@
txn, resourceID=self._resourceID, value=value_str,
name=key_str, uid=uid)
self._cacher.delete(str(self._resourceID))
+
+ # Call the registered notification callback
+ if hasattr(self, "_notifyCallback") and self._notifyCallback is not None:
+ self._notifyCallback()
+
self._txn.subtransaction(trySetItem)
Modified: CalendarServer/trunk/txdav/caldav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2012-07-17 00:20:24 UTC (rev 9458)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/common.py 2012-07-17 20:32:21 UTC (rev 9459)
@@ -717,8 +717,7 @@
yield self.commit()
# Make sure notification fired after commit
- self.assertEquals(self.notifierFactory.history,
- [("update", "CalDAV|home1")])
+ self.assertTrue(("update", "CalDAV|home1") in self.notifierFactory.history)
# Make sure it's available in a new transaction; i.e. test the commit.
home = yield self.homeUnderTest()
Modified: CalendarServer/trunk/txdav/carddav/datastore/test/common.py
===================================================================
--- CalendarServer/trunk/txdav/carddav/datastore/test/common.py 2012-07-17 00:20:24 UTC (rev 9458)
+++ CalendarServer/trunk/txdav/carddav/datastore/test/common.py 2012-07-17 20:32:21 UTC (rev 9459)
@@ -329,8 +329,7 @@
yield self.commit()
# Make sure notification fired after commit
- self.assertEquals(self.notifierFactory.history,
- [("update", "CardDAV|home1")])
+ self.assertTrue(("update", "CardDAV|home1") in self.notifierFactory.history)
# Make sure it's available in a new transaction; i.e. test the commit.
home = yield self.homeUnderTest()
Modified: CalendarServer/trunk/txdav/common/datastore/file.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/file.py 2012-07-17 00:20:24 UTC (rev 9458)
+++ CalendarServer/trunk/txdav/common/datastore/file.py 2012-07-17 20:32:21 UTC (rev 9459)
@@ -208,6 +208,7 @@
self._notificationHomes = {}
self._notifierFactory = notifierFactory
self._notifiedAlready = set()
+ self._bumpedAlready = set()
self._migrating = migrating
extraInterfaces = []
@@ -267,11 +268,28 @@
def isNotifiedAlready(self, obj):
return obj in self._notifiedAlready
-
+
def notificationAddedForObject(self, obj):
self._notifiedAlready.add(obj)
+ def isBumpedAlready(self, obj):
+ """
+ Indicates whether or not bumpAddedForObject has already been
+ called for the given object, in order to facilitate calling
+ bumpModified only once per object.
+ """
+ return obj in self._bumpedAlready
+ def bumpAddedForObject(self, obj):
+ """
+ Records the fact that a bumpModified( ) call has already been
+ done, in order to facilitate calling bumpModified only once per
+ object.
+ """
+ self._bumpedAlready.add(obj)
+
+
+
class StubResource(object):
"""
Just enough resource to keep the shared sql DB classes going.
Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py 2012-07-17 00:20:24 UTC (rev 9458)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py 2012-07-17 20:32:21 UTC (rev 9459)
@@ -321,6 +321,7 @@
self._postAbortOperations = []
self._notifierFactory = notifierFactory
self._notifiedAlready = set()
+ self._bumpedAlready = set()
self._label = label
self._migrating = migrating
self._primaryHomeType = None
@@ -565,10 +566,26 @@
def isNotifiedAlready(self, obj):
return obj in self._notifiedAlready
-
+
def notificationAddedForObject(self, obj):
self._notifiedAlready.add(obj)
+ def isBumpedAlready(self, obj):
+ """
+ Indicates whether or not bumpAddedForObject has already been
+ called for the given object, in order to facilitate calling
+ bumpModified only once per object.
+ """
+ return obj in self._bumpedAlready
+
+ def bumpAddedForObject(self, obj):
+ """
+ Records the fact that a bumpModified( ) call has already been
+ done, in order to facilitate calling bumpModified only once per
+ object.
+ """
+ self._bumpedAlready.add(obj)
+
_savepointCounter = 0
def _savepoint(self):
@@ -1338,7 +1355,8 @@
props = yield PropertyStore.load(
self.uid(),
self._txn,
- self._resourceID
+ self._resourceID,
+ notifyCallback=self.notifyChanged
)
self._propertyStore = props
@@ -1539,6 +1557,10 @@
delay the transaction whilst waiting for deadlock detection to kick in.
"""
+ if self._txn.isBumpedAlready(self):
+ returnValue(None)
+ self._txn.bumpAddedForObject(self)
+
# NB if modified is bumped we know that sync token will have changed too, so invalidate the cached value
self._syncTokenRevision = None
@@ -1557,13 +1579,13 @@
except AllRetriesFailed:
log.debug("CommonHome.bumpModified failed")
-
+
@inlineCallbacks
def notifyChanged(self):
"""
Trigger a notification of a change
"""
-
+
# Update modified if object still exists
if self._resourceID:
yield self.bumpModified()
@@ -2914,7 +2936,8 @@
props = yield PropertyStore.load(
self.ownerHome().uid(),
self._txn,
- self._resourceID
+ self._resourceID,
+ notifyCallback=self.notifyChanged
)
self.initPropertyStore(props)
self._properties = props
@@ -3003,12 +3026,16 @@
delay the transaction whilst waiting for deadlock detection to kick in.
"""
+ if self._txn.isBumpedAlready(self):
+ returnValue(None)
+ self._txn.bumpAddedForObject(self)
+
@inlineCallbacks
def _bumpModified(subtxn):
yield self._lockLastModifiedQuery.on(subtxn, resourceID=self._resourceID)
result = (yield self._changeLastModifiedQuery.on(subtxn, resourceID=self._resourceID))
returnValue(result)
-
+
try:
self._modified = (yield self._txn.subtransaction(_bumpModified, retries=0, failureOK=True))[0][0]
@@ -3018,13 +3045,13 @@
yield queryCacher.invalidateAfterCommit(self._txn, cacheKey)
except AllRetriesFailed:
log.debug("CommonHomeChild.bumpModified failed")
-
+
@inlineCallbacks
def notifyChanged(self):
"""
Trigger a notification of a change
"""
-
+
# Update modified if object still exists
if self._resourceID:
yield self.bumpModified()
@@ -3036,7 +3063,6 @@
self._txn.notificationAddedForObject(self)
-
class CommonObjectResource(LoggingMixIn, FancyEqMixin):
"""
Base class for object resources.
@@ -3507,7 +3533,8 @@
self._propertyStore = yield PropertyStore.load(
self._uid,
self._txn,
- self._resourceID
+ self._resourceID,
+ notifyCallback=self.notifyChanged
)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120717/cd834f1c/attachment-0001.html>
More information about the calendarserver-changes
mailing list