[CalendarServer-changes] [6491] CalendarServer/branches/users/glyph/sharedpool/txdav

source_changes at macosforge.org source_changes at macosforge.org
Mon Nov 1 14:11:16 PDT 2010


Revision: 6491
          http://trac.macosforge.org/projects/calendarserver/changeset/6491
Author:   glyph at apple.com
Date:     2010-11-01 14:11:10 -0700 (Mon, 01 Nov 2010)
Log Message:
-----------
separate sql transaction from logical transaction

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/sharedpool/txdav/base/datastore/subpostgres.py
    CalendarServer/branches/users/glyph/sharedpool/txdav/common/datastore/sql.py
    CalendarServer/branches/users/glyph/sharedpool/txdav/idav.py

Modified: CalendarServer/branches/users/glyph/sharedpool/txdav/base/datastore/subpostgres.py
===================================================================
--- CalendarServer/branches/users/glyph/sharedpool/txdav/base/datastore/subpostgres.py	2010-11-01 21:06:58 UTC (rev 6490)
+++ CalendarServer/branches/users/glyph/sharedpool/txdav/base/datastore/subpostgres.py	2010-11-01 21:11:10 UTC (rev 6491)
@@ -402,7 +402,7 @@
     def unpauseMonitor(self):
         """
         Unpause monitoring.
-        
+
         @see: L{pauseMonitor} 
         """
 #        for pipe in self.monitor.transport.pipes.values():

Modified: CalendarServer/branches/users/glyph/sharedpool/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/glyph/sharedpool/txdav/common/datastore/sql.py	2010-11-01 21:06:58 UTC (rev 6490)
+++ CalendarServer/branches/users/glyph/sharedpool/txdav/common/datastore/sql.py	2010-11-01 21:11:10 UTC (rev 6491)
@@ -60,10 +60,12 @@
     NoSuchObjectResourceError
 from txdav.common.inotifications import INotificationCollection, \
     INotificationObject
+from txdav.idav import IAsyncTransaction
+from txdav.idav import AlreadyFinishedError
 
-from txdav.idav import AlreadyFinishedError
+
+from txdav.base.propertystore.sql import PropertyStore
 from txdav.base.propertystore.base import PropertyName
-from txdav.base.propertystore.sql import PropertyStore
 
 from twistedcaldav.customxml import NotificationType
 from twistedcaldav.dateops import datetimeMktime
@@ -211,44 +213,19 @@
 
 
 
-class CommonStoreTransaction(object):
+class ThisProcessSqlTxn(object):
     """
-    Transaction implementation for SQL database.
+    L{IAsyncTransaction} implementation based on a L{ThreadHolder} in the
+    current process.
     """
-    _homeClass = {}
-    _homeTable = {}
+    implements(IAsyncTransaction)
 
-    noisy = False
-    id = 0
-
-    def __init__(self, store, connectionFactory,
-                 enableCalendars, enableAddressBooks,
-                 notifierFactory, label, migrating=False):
-        self._store = store
+    def __init__(self, connectionFactory):
+        """
+        @param connectionFactory: A 0-argument callable which returns a DB-API
+            2.0 connection.
+        """
         self._completed = False
-        self._calendarHomes = {}
-        self._addressbookHomes = {}
-        self._notificationHomes = {}
-        self._postCommitOperations = []
-        self._notifierFactory = notifierFactory
-        self._label = label
-        self._migrating = migrating
-        CommonStoreTransaction.id += 1
-        self._txid = CommonStoreTransaction.id
-
-        extraInterfaces = []
-        if enableCalendars:
-            extraInterfaces.append(ICalendarTransaction)
-        if enableAddressBooks:
-            extraInterfaces.append(IAddressBookTransaction)
-        directlyProvides(self, *extraInterfaces)
-
-        from txdav.caldav.datastore.sql import CalendarHome
-        from txdav.carddav.datastore.sql import AddressBookHome
-        CommonStoreTransaction._homeClass[ECALENDARTYPE] = CalendarHome
-        CommonStoreTransaction._homeClass[EADDRESSBOOKTYPE] = AddressBookHome
-        CommonStoreTransaction._homeTable[ECALENDARTYPE] = CALENDAR_HOME_TABLE
-        CommonStoreTransaction._homeTable[EADDRESSBOOKTYPE] = ADDRESSBOOK_HOME_TABLE
         self._holder = ThreadHolder(reactor)
         self._holder.start()
         def initCursor():
@@ -298,13 +275,88 @@
         return result
 
 
+    def commit(self):
+        if not self._completed:
+            self._completed = True
+            def reallyCommit():
+                self._connection.commit()
+                self._connection.close()
+            result = self._holder.submit(reallyCommit)
+            self._holder.stop()
+            return result
+        else:
+            raise AlreadyFinishedError()
+
+
+    def abort(self):
+        if not self._completed:
+            def reallyAbort():
+                self._connection.rollback()
+                self._connection.close()
+            self._completed = True
+            result = self._holder.submit(reallyAbort)
+            self._holder.stop()
+            return result
+        else:
+            raise AlreadyFinishedError()
+
+
     def __del__(self):
         if not self._completed:
             print "CommonStoreTransaction.__del__: OK"
             self.abort()
 
 
-    @memoizedKey("uid", "_calendarHomes")
+
+class CommonStoreTransaction(object):
+    """
+    Transaction implementation for SQL database.
+    """
+    _homeClass = {}
+    _homeTable = {}
+
+    id = 0
+
+    def __init__(self, store, cursorFactory,
+                 enableCalendars, enableAddressBooks,
+                 notifierFactory, label, migrating=False):
+        self._store = store
+        self._calendarHomes = {}
+        self._addressbookHomes = {}
+        self._notificationHomes = {}
+        self._postCommitOperations = []
+        self._notifierFactory = notifierFactory
+        self._label = label
+        self._migrating = migrating
+
+        CommonStoreTransaction.id += 1
+        self._txid = CommonStoreTransaction.id
+
+        extraInterfaces = []
+        if enableCalendars:
+            extraInterfaces.append(ICalendarTransaction)
+        if enableAddressBooks:
+            extraInterfaces.append(IAddressBookTransaction)
+        directlyProvides(self, *extraInterfaces)
+
+        from txdav.caldav.datastore.sql import CalendarHome
+        from txdav.carddav.datastore.sql import AddressBookHome
+        CommonStoreTransaction._homeClass[ECALENDARTYPE] = CalendarHome
+        CommonStoreTransaction._homeClass[EADDRESSBOOKTYPE] = AddressBookHome
+        CommonStoreTransaction._homeTable[ECALENDARTYPE] = CALENDAR_HOME_TABLE
+        CommonStoreTransaction._homeTable[EADDRESSBOOKTYPE] = ADDRESSBOOK_HOME_TABLE
+        self._sqlTxn = ThisProcessSqlTxn(cursorFactory)
+
+
+    def store(self):
+        return self._store
+
+
+    def __repr__(self):
+        return 'PG-TXN<%s>' % (self._label,)
+
+
+    @memoizedKey('uid', '_calendarHomes')
     def calendarHomeWithUID(self, uid, create=False):
         return self.homeWithUID(ECALENDARTYPE, uid, create=create)
 
@@ -409,40 +461,35 @@
         returnValue(collection)
 
 
-    def abort(self):
-        if not self._completed:
-            def reallyAbort():
-                self._connection.rollback()
-                self._connection.close()
-            self._completed = True
-            result = self._holder.submit(reallyAbort)
-            self._holder.stop()
-            return result
-        else:
-            raise AlreadyFinishedError()
+    def postCommit(self, operation):
+        """
+        Run things after C{commit}.
+        """
+        self._postCommitOperations.append(operation)
 
 
+    def execSQL(self, *a, **kw):
+        """
+        """
+        return self._sqlTxn.execSQL(*a, **kw)
+
+
     def commit(self):
-        if not self._completed:
-            self._completed = True
-            def postCommit(ignored):
-                for operation in self._postCommitOperations:
-                    operation()
-            def reallyCommit():
-                self._connection.commit()
-                self._connection.close()
-            result = self._holder.submit(reallyCommit).addCallback(postCommit)
-            self._holder.stop()
-            return result
-        else:
-            raise AlreadyFinishedError()
+        """
+        Commit the transaction and return 
+        """
+        def postCommit(ignored):
+            for operation in self._postCommitOperations:
+                operation()
+            return ignored
+        return self._sqlTxn.commit().addCallback(postCommit)
 
 
-    def postCommit(self, operation):
+    def abort(self):
         """
-        Run things after C{commit}.
+        docstring for abort
         """
-        self._postCommitOperations.append(operation)
+        return self._sqlTxn.abort()
 
 
 
@@ -717,13 +764,14 @@
             raise NoSuchHomeChildError()
         yield child._deletedSyncToken()
 
-        yield self._txn.execSQL(
-            "delete from %(name)s where %(column_RESOURCE_ID)s = %%s" % self._childTable,
-            [child._resourceID]
-        )
-        self._children.pop(name, None)
-        if self._txn._cursor.rowcount == 0:
-            raise NoSuchHomeChildError()
+        try:
+            yield self._txn.execSQL(
+                "delete from %(name)s where %(column_RESOURCE_ID)s = %%s" % self._childTable,
+                [child._resourceID],
+                raiseOnZeroRowCount=NoSuchHomeChildError
+            )
+        finally:
+            self._children.pop(name, None)
 
         child.notifyChanged()
 

Modified: CalendarServer/branches/users/glyph/sharedpool/txdav/idav.py
===================================================================
--- CalendarServer/branches/users/glyph/sharedpool/txdav/idav.py	2010-11-01 21:06:58 UTC (rev 6490)
+++ CalendarServer/branches/users/glyph/sharedpool/txdav/idav.py	2010-11-01 21:11:10 UTC (rev 6491)
@@ -172,6 +172,33 @@
 
 
 
+class IAsyncTransaction(Interface):
+    """
+    Asynchronous execution of SQL.
+
+    Note that there is no {begin()} method; if an L{IAsyncTransaction} exists,
+    it is assumed to have been started.
+    """
+
+    def execSQL(sql, args):
+        """
+        Execute some SQL.
+
+        @return: L{Deferred} which fires C{list} of C{tuple}
+        """
+
+
+    def commit():
+        """
+        """
+
+
+    def abort():
+        """
+        """
+
+
+
 class ITransaction(Interface):
     """
     Transaction that can be aborted and either succeeds or fails in
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20101101/1dcc0c27/attachment-0001.html>


More information about the calendarserver-changes mailing list