[CalendarServer-changes] [9660] CalendarServer/branches/users/glyph/q
source_changes at macosforge.org
source_changes at macosforge.org
Sat Aug 11 01:55:32 PDT 2012
Revision: 9660
http://trac.macosforge.org/projects/calendarserver/changeset/9660
Author: glyph at apple.com
Date: 2012-08-11 01:55:31 -0700 (Sat, 11 Aug 2012)
Log Message:
-----------
push postCommit/postAbort hooks down into the SQL store.
Modified Paths:
--------------
CalendarServer/branches/users/glyph/q/twext/enterprise/adbapi2.py
CalendarServer/branches/users/glyph/q/twext/enterprise/ienterprise.py
CalendarServer/branches/users/glyph/q/txdav/base/datastore/file.py
CalendarServer/branches/users/glyph/q/txdav/base/datastore/util.py
CalendarServer/branches/users/glyph/q/txdav/common/datastore/sql.py
CalendarServer/branches/users/glyph/q/txdav/idav.py
Property Changed:
----------------
CalendarServer/branches/users/glyph/q/
Modified: CalendarServer/branches/users/glyph/q/twext/enterprise/adbapi2.py
===================================================================
--- CalendarServer/branches/users/glyph/q/twext/enterprise/adbapi2.py 2012-08-11 08:55:30 UTC (rev 9659)
+++ CalendarServer/branches/users/glyph/q/twext/enterprise/adbapi2.py 2012-08-11 08:55:31 UTC (rev 9660)
@@ -484,7 +484,53 @@
-class _SingleTxn(proxyForInterface(iface=IAsyncTransaction,
+class _HookableOperation(object):
+
+ def __init__(self):
+ self._hooks = []
+
+
+ @inlineCallbacks
+ def runHooks(self, ignored):
+ """
+ Callback for C{commit} and C{abort} Deferreds.
+ """
+ for operation in self._hooks:
+ yield operation()
+ returnValue(ignored)
+
+
+ def addHook(self, operation):
+ """
+ Implement L{IAsyncTransaction.postCommit}.
+ """
+ self._hooks.append(operation)
+
+
+
+class _CommitAndAbortHooks(object):
+ """
+ Shared implementation of post-commit and post-abort hooks.
+ """
+ # FIXME: this functionality needs direct tests, although it's pretty well-
+ # covered by txdav's test suite.
+
+ def __init__(self):
+ self._commit = _HookableOperation()
+ self._abort = _HookableOperation()
+
+
+ def postCommit(self, operation):
+ return self._commit.addHook(operation)
+
+
+ def postAbort(self, operation):
+ return self._abort.addHook(operation)
+
+
+
+class _SingleTxn(_CommitAndAbortHooks,
+ proxyForInterface(iface=IAsyncTransaction,
originalAttribute='_baseTxn')):
"""
A L{_SingleTxn} is a single-use wrapper for the longer-lived
@@ -505,6 +551,7 @@
"""
def __init__(self, pool, baseTxn):
+ super(_SingleTxn, self).__init__()
self._pool = pool
self._baseTxn = baseTxn
self._completed = False
@@ -601,9 +648,9 @@
# We're in the process of executing a block of commands. Wait until
# they're done. (Commit will be repeated in _checkNextBlock.)
return self._blockedQueue.commit()
-
self._markComplete()
- return super(_SingleTxn, self).commit()
+ return (super(_SingleTxn, self).commit()
+ .addCallback(self._commit.runHooks))
def abort(self):
@@ -611,6 +658,7 @@
result = super(_SingleTxn, self).abort()
if self in self._pool._waiting:
self._stopWaiting()
+ result.addCallback(self._abort.runHooks)
return result
@@ -1432,7 +1480,7 @@
-class _NetTransaction(object):
+class _NetTransaction(_CommitAndAbortHooks):
"""
A L{_NetTransaction} is an L{AMP}-protocol-based provider of the
L{IAsyncTransaction} interface. It sends SQL statements, query results, and
@@ -1446,6 +1494,7 @@
Initialize a transaction with a L{ConnectionPoolClient} and a unique
transaction identifier.
"""
+ super(_NetTransaction, self).__init__()
self._client = client
self._transactionID = transactionID
self._completed = False
@@ -1503,11 +1552,12 @@
def done(whatever):
self._committed = True
return whatever
- return self._complete(Commit).addBoth(done)
+ return (self._complete(Commit).addBoth(done)
+ .addCallback(self._commit.runHooks))
def abort(self):
- return self._complete(Abort)
+ return self._complete(Abort).addCallback(self._abort.runHooks)
def commandBlock(self):
Modified: CalendarServer/branches/users/glyph/q/twext/enterprise/ienterprise.py
===================================================================
--- CalendarServer/branches/users/glyph/q/twext/enterprise/ienterprise.py 2012-08-11 08:55:30 UTC (rev 9659)
+++ CalendarServer/branches/users/glyph/q/twext/enterprise/ienterprise.py 2012-08-11 08:55:31 UTC (rev 9660)
@@ -103,6 +103,18 @@
"""
+ def postCommit(operation):
+ """
+ Perform the given operation only after this L{IAsyncTransaction}
+ commits. These will be invoked before the L{Deferred} returned by
+ L{IAsyncTransaction.commit} fires.
+
+ @param operation: a 0-argument callable that may return a L{Deferred}.
+ If it does, then the subsequent operations added by L{postCommit}
+ will not fire until that L{Deferred} fires.
+ """
+
+
def abort():
"""
Roll back changes caused by this transaction.
@@ -112,6 +124,17 @@
"""
+ def postAbort(operation):
+ """
+ Invoke a callback after abort.
+
+ @see: L{IAsyncTransaction.postCommit}
+
+ @param operation: 0-argument callable, potentially returning a
+ L{Deferred}.
+ """
+
+
def commandBlock():
"""
Create an object which will cause the commands executed on it to be
Modified: CalendarServer/branches/users/glyph/q/txdav/base/datastore/file.py
===================================================================
--- CalendarServer/branches/users/glyph/q/txdav/base/datastore/file.py 2012-08-11 08:55:30 UTC (rev 9659)
+++ CalendarServer/branches/users/glyph/q/txdav/base/datastore/file.py 2012-08-11 08:55:31 UTC (rev 9660)
@@ -187,15 +187,19 @@
self.log_error("Cannot undo DataStoreTransaction")
raise
- for (operation, ignored) in self._postCommitOperations:
+ for operation in self._postCommitOperations:
operation()
- def postCommit(self, operation, immediately=False):
- self._postCommitOperations.append((operation, immediately))
+ def postCommit(self, operation):
+ self._postCommitOperations.append(operation)
+
+
def postAbort(self, operation):
self._postAbortOperations.append(operation)
+
+
class FileMetaDataMixin(object):
implements(IDataStoreObject)
Modified: CalendarServer/branches/users/glyph/q/txdav/base/datastore/util.py
===================================================================
--- CalendarServer/branches/users/glyph/q/txdav/base/datastore/util.py 2012-08-11 08:55:30 UTC (rev 9659)
+++ CalendarServer/branches/users/glyph/q/txdav/base/datastore/util.py 2012-08-11 08:55:31 UTC (rev 9660)
@@ -70,13 +70,19 @@
def setAfterCommit(self, transaction, key, value):
- transaction.postCommit(lambda: self.set(key, value), immediately=True)
+ def setit():
+ # Don't return Deferred; let the postCommit chain continue.
+ self.set(key, value)
+ transaction.postCommit(setit)
def invalidateAfterCommit(self, transaction, key):
# Invalidate now (so that operations within this transaction see it)
# and *also* post-commit (because there could be a scheduled setAfterCommit
# for this key)
- transaction.postCommit(lambda: self.delete(key), immediately=True)
+ def delit():
+ # Don't return Deferred; let the postCommit chain continue.
+ self.delete(key)
+ transaction.postCommit(delit)
return self.delete(key)
# Home child objects by name
Modified: CalendarServer/branches/users/glyph/q/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/glyph/q/txdav/common/datastore/sql.py 2012-08-11 08:55:30 UTC (rev 9659)
+++ CalendarServer/branches/users/glyph/q/txdav/common/datastore/sql.py 2012-08-11 08:55:31 UTC (rev 9660)
@@ -350,8 +350,6 @@
self._calendarHomes = {}
self._addressbookHomes = {}
self._notificationHomes = {}
- self._postCommitOperations = []
- self._postAbortOperations = []
self._notifierFactory = notifierFactory
self._notifiedAlready = set()
self._bumpedAlready = set()
@@ -606,18 +604,18 @@
return self._apnSubscriptionsBySubscriberQuery.on(self, subscriberGUID=guid)
- def postCommit(self, operation, immediately=False):
+ def postCommit(self, operation):
"""
Run things after C{commit}.
"""
- self._postCommitOperations.append((operation, immediately))
+ return self._sqlTxn.postCommit(operation)
def postAbort(self, operation):
"""
Run things after C{abort}.
"""
- self._postAbortOperations.append(operation)
+ return self._sqlTxn.postAbort(operation)
def isNotifiedAlready(self, obj):
@@ -774,30 +772,16 @@
"""
Commit the transaction and execute any post-commit hooks.
"""
- @inlineCallbacks
- def postCommit(ignored):
- for operation, immediately in self._postCommitOperations:
- if immediately:
- yield operation()
- else:
- operation()
- returnValue(ignored)
-
if self._stats:
self._stats.printReport()
+ return self._sqlTxn.commit()
- return self._sqlTxn.commit().addCallback(postCommit)
-
def abort(self):
"""
Abort the transaction.
"""
- def postAbort(ignored):
- for operation in self._postAbortOperations:
- operation()
- return ignored
- return self._sqlTxn.abort().addCallback(postAbort)
+ return self._sqlTxn.abort()
def _oldEventsBase(limited): #@NoSelf
Modified: CalendarServer/branches/users/glyph/q/txdav/idav.py
===================================================================
--- CalendarServer/branches/users/glyph/q/txdav/idav.py 2012-08-11 08:55:30 UTC (rev 9659)
+++ CalendarServer/branches/users/glyph/q/txdav/idav.py 2012-08-11 08:55:31 UTC (rev 9660)
@@ -207,29 +207,15 @@
"""
- def postCommit(operation, immediately=False):
+ def postCommit(operation):
"""
- Registers an operation to be executed after the transaction is
- committed.
-
- postCommit can be called multiple times, and operations are executed
- in the order which they were registered.
-
- @param operation: a callable.
- @param immediately: a boolean; True means finish this operation *before* the
- commit( ) call completes, defaults to False.
+ @see: L{IAsyncTransaction.postCommit}
"""
def postAbort(operation):
"""
- Registers an operation to be executed after the transaction is
- aborted.
-
- postAbort can be called multiple times, and operations are executed
- in the order which they were registered.
-
- @param operation: a callable.
+ @see: L{IAsyncTransaction.postAbort}
"""
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120811/739f0614/attachment-0001.html>
More information about the calendarserver-changes
mailing list