[CalendarServer-changes] [7252] CalendarServer/branches/users/glyph/subtransactions/twext/enterprise
source_changes at macosforge.org
source_changes at macosforge.org
Thu Mar 24 13:36:07 PDT 2011
Revision: 7252
http://trac.macosforge.org/projects/calendarserver/changeset/7252
Author: glyph at apple.com
Date: 2011-03-24 13:36:07 -0700 (Thu, 24 Mar 2011)
Log Message:
-----------
test for one command block following another, and (apparently wrong) fix for that
Modified Paths:
--------------
CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/adbapi2.py
CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/test/test_adbapi2.py
Modified: CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/adbapi2.py
===================================================================
--- CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/adbapi2.py 2011-03-24 20:35:56 UTC (rev 7251)
+++ CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/adbapi2.py 2011-03-24 20:36:07 UTC (rev 7252)
@@ -1,4 +1,3 @@
-from twext.enterprise.ienterprise import IDerivedParameter
# -*- test-case-name: twext.enterprise.test.test_adbapi2 -*-
##
# Copyright (c) 2010 Apple Inc. All rights reserved.
@@ -53,7 +52,10 @@
from twext.internet.threadutils import ThreadHolder
from twisted.internet.defer import succeed
+
from twext.enterprise.ienterprise import ConnectionError
+from twext.enterprise.ienterprise import IDerivedParameter
+
from twisted.internet.defer import fail
from twext.enterprise.ienterprise import (
AlreadyFinishedError, IAsyncTransaction, POSTGRES_DIALECT
@@ -362,7 +364,7 @@
self._complete = False
self._currentBlock = None
self._pendingBlocks = []
- self._allPending = []
+ self._stillExecuting = []
self._blockedQueue = None
@@ -396,10 +398,11 @@
self._checkComplete()
if block is None and self._blockedQueue is not None:
return self._blockedQueue.execSQL(sql, args, raiseOnZeroRowCount)
+ # 'block' should always be _currentBlock at this point.
d = super(_SingleTxn, self).execSQL(sql, args, raiseOnZeroRowCount)
- self._allPending.append(d)
+ self._stillExecuting.append(d)
def itsDone(result):
- self._allPending.remove(d)
+ self._stillExecuting.remove(d)
self._checkNextBlock()
return result
d.addBoth(itsDone)
@@ -412,7 +415,7 @@
execute, and execute the next one if there are no outstanding execute
calls.
"""
- if self._allPending:
+ if self._stillExecuting:
return
if self._pendingBlocks and self._currentBlock is None:
@@ -431,8 +434,7 @@
bq = self._blockedQueue
self._blockedQueue = None
bq._unspool(self)
- # XXX need to check next block, there might have been nothing in the
- # blocked executing queue.
+ self._checkNextBlock()
def commit(self):
@@ -474,14 +476,18 @@
def commandBlock(self):
"""
- Create an IAsyncTransaction that will wait for all currently spooled
+ Create a L{CommandBlock} which will wait for all currently spooled
commands to complete before executing its own.
"""
- self._currentBlock = CommandBlock(self)
- self._blockedQueue = _WaitingTxn(self._pool)
- # FIXME: test the case where it's ready immediately.
- self._checkNextBlock()
- return self._currentBlock
+ block = CommandBlock(self)
+ if self._currentBlock is None:
+ self._currentBlock = block
+ self._blockedQueue = _WaitingTxn(self._pool)
+ # FIXME: test the case where it's ready immediately.
+ self._checkNextBlock()
+ else:
+ self._pendingBlocks.append(block)
+ return block
@@ -557,8 +563,9 @@
"""
# FIXME: test the case where end() is called when it's not the current
# executing block.
+ if self._ended:
+ raise AlreadyFinishedError()
self._ended = True
- self._singleTxn._checkNextBlock()
DeferredList(self._waitingForEnd).chainDeferred(self._endDeferred)
Modified: CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/test/test_adbapi2.py
===================================================================
--- CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/test/test_adbapi2.py 2011-03-24 20:35:56 UTC (rev 7251)
+++ CalendarServer/branches/users/glyph/subtransactions/twext/enterprise/test/test_adbapi2.py 2011-03-24 20:36:07 UTC (rev 7252)
@@ -27,6 +27,7 @@
from twisted.internet.defer import Deferred
from twext.enterprise.ienterprise import ConnectionError
+from twext.enterprise.ienterprise import AlreadyFinishedError
from twext.enterprise.adbapi2 import ConnectionPool
@@ -918,3 +919,43 @@
self.assertEquals(len(d), 1)
self.assertEquals(len(e), 1)
+
+ def test_twoCommandBlocks(self, flush=lambda : None):
+ """
+ When execution of one command block is complete, it will proceed to the
+ next queued block, then to regular SQL executed on the transaction.
+ """
+ txn = self.pool.connection()
+ cb1 = txn.commandBlock()
+ cb2 = txn.commandBlock()
+ txn.execSQL("e")
+ cb1.execSQL("a")
+ cb2.execSQL("c")
+ cb1.execSQL("b")
+ cb2.execSQL("d")
+ cb2.end()
+ cb1.end()
+ flush()
+ self.assertEquals(self.factory.connections[0].cursors[0].allExecutions,
+ [("a", []), ("b", []), ("c", []), ("d", []),
+ ("e", [])])
+
+
+ def test_twoCommandBlocksLatently(self):
+ """
+ Same as L{test_twoCommandBlocks}, but with slower callbacks.
+ """
+ self.pauseHolders()
+ self.test_twoCommandBlocks(self.flushHolders)
+
+
+ def test_commandBlockEndTwice(self):
+ """
+ L{CommandBlock.end} will raise L{AlreadyFinishedError} when called more
+ than once.
+ """
+ txn = self.pool.connection()
+ block = txn.commandBlock()
+ block.end()
+ self.assertRaises(AlreadyFinishedError, block.end)
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110324/34b84a1c/attachment.html>
More information about the calendarserver-changes
mailing list