[Zodb-checkins] CVS: ZODB3/ZEO - ClientStorage.py:1.106.2.1
Tim Peters
tim.one at comcast.net
Tue Aug 5 18:59:08 EDT 2003
Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv21586/ZEO
Modified Files:
Tag: ZODB3-3_2-branch
ClientStorage.py
Log Message:
Forward-porting critical ZEO client fixes from ZODB3-3_1-boston-branch.
+ If a storage times out between the vote and the finish, the ZEO cache
could get populated with objects that don't make it to the storage
server.
A new flag self._midtxn_disconnect gets reset in tpc_begin() and set
in notifyDisconnected(). If tpc_finish() discovers this flag set, it
raises a ClientDisconnected error before calling tpc_finish() on the
server.
+ In tpc_finish() we re-order the calls so that the server's tpc_finish()
is called (and must succeed) before we update the ZEO client cache.
+ The storage name is now prepended to the sort key, to ensure a
unique global sort order if storages are named uniquely.
+ Added new tests for the above (checkTimeoutAfterVote,
checkTimeoutProvokingConflicts, checkSortKey).
=== ZODB3/ZEO/ClientStorage.py 1.106 => 1.106.2.1 ===
--- ZODB3/ZEO/ClientStorage.py:1.106 Mon Jun 16 13:17:42 2003
+++ ZODB3/ZEO/ClientStorage.py Tue Aug 5 17:58:33 2003
@@ -232,6 +232,11 @@
self._username = username
self._password = password
self._realm = realm
+
+ # Flag tracking disconnections in the middle of a transaction. This
+ # is reset in tpc_begin() and set in notifyDisconnected().
+ self._midtxn_disconnect = 0
+
# _server_addr is used by sortKey()
self._server_addr = None
self._tfile = None
@@ -514,7 +519,7 @@
if self._server_addr is None:
raise ClientDisconnected
else:
- return self._server_addr
+ return '%s:%s' % (self._storage, self._server_addr)
def verify_cache(self, server):
"""Internal routine called to verify the cache.
@@ -583,6 +588,7 @@
self._connection = None
self._ready.clear()
self._server = disconnected_stub
+ self._midtxn_disconnect = 1
def __len__(self):
"""Return the size of the storage."""
@@ -821,6 +827,7 @@
if self._is_read_only:
raise POSException.ReadOnlyError()
self._tpc_cond.acquire()
+ self._midtxn_disconnect = 0
while self._transaction is not None:
# It is allowable for a client to call two tpc_begins in a
# row with the same transaction, and the second of these
@@ -891,6 +898,12 @@
return
self._load_lock.acquire()
try:
+ if self._midtxn_disconnect:
+ raise ClientDisconnected(
+ 'Calling tpc_finish() on a disconnected transaction')
+
+ tid = self._server.tpc_finish(self._serial)
+
self._lock.acquire() # for atomic processing of invalidations
try:
self._update_cache()
@@ -898,8 +911,6 @@
f()
finally:
self._lock.release()
-
- tid = self._server.tpc_finish(self._serial)
self._cache.setLastTid(tid)
r = self._check_serials()
More information about the Zodb-checkins
mailing list