[Zodb-checkins] SVN: ZODB/branches/3.9/src/ZEO/cache.py Fix an egregious bug that caused caches to fail when run with an
Jim Fulton
jim at zope.com
Tue Apr 20 17:46:50 EDT 2010
Log message for revision 111193:
Fix an egregious bug that caused caches to fail when run with an
optimized Python. :(
Changed:
U ZODB/branches/3.9/src/ZEO/cache.py
-=-
Modified: ZODB/branches/3.9/src/ZEO/cache.py
===================================================================
--- ZODB/branches/3.9/src/ZEO/cache.py 2010-04-20 21:46:48 UTC (rev 111192)
+++ ZODB/branches/3.9/src/ZEO/cache.py 2010-04-20 21:46:49 UTC (rev 111193)
@@ -39,19 +39,19 @@
logger = logging.getLogger("ZEO.cache")
# A disk-based cache for ZEO clients.
-#
+#
# This class provides an interface to a persistent, disk-based cache
# used by ZEO clients to store copies of database records from the
# server.
-#
+#
# The details of the constructor as unspecified at this point.
-#
+#
# Each entry in the cache is valid for a particular range of transaction
# ids. The lower bound is the transaction that wrote the data. The
# upper bound is the next transaction that wrote a revision of the
# object. If the data is current, the upper bound is stored as None;
# the data is considered current until an invalidate() call is made.
-#
+#
# It is an error to call store() twice with the same object without an
# intervening invalidate() to set the upper bound on the first cache
# entry. Perhaps it will be necessary to have a call the removes
@@ -59,12 +59,12 @@
# entry.
# Cache verification
-#
+#
# When the client is connected to the server, it receives
# invalidations every time an object is modified. When the client is
# disconnected then reconnects, it must perform cache verification to make
# sure its cached data is synchronized with the storage's current state.
-#
+#
# quick verification
# full verification
#
@@ -206,7 +206,7 @@
self.f = tempfile.TemporaryFile()
self.f.write(magic+z64)
logger.info("created temporary cache file %r", self.f.name)
-
+
self._initfile(fsize)
# Statistics: _n_adds, _n_added_bytes,
@@ -328,7 +328,7 @@
seek(block_size-5, 1)
sync(self.f)
- # There is always data to read and
+ # There is always data to read and
assert last and status in ' f1234'
first_free_offset = last
else:
@@ -358,7 +358,7 @@
except KeyError:
logger.error("Couldn't find non-current %r", (oid, tid))
-
+
def clearStats(self):
self._n_adds = self._n_added_bytes = 0
self._n_evicts = self._n_evicted_bytes = 0
@@ -471,7 +471,8 @@
return None
self.f.seek(ofs)
read = self.f.read
- assert read(1) == 'a', (ofs, self.f.tell(), oid)
+ status = read(1)
+ assert status == 'a', (ofs, self.f.tell(), oid)
size, saved_oid, tid, end_tid, lver, ldata = unpack(
">I8s8s8sHI", read(34))
assert saved_oid == oid, (ofs, self.f.tell(), oid, saved_oid)
@@ -479,8 +480,11 @@
data = read(ldata)
assert len(data) == ldata, (ofs, self.f.tell(), oid, len(data), ldata)
- assert read(8) == oid, (ofs, self.f.tell(), oid)
+ # WARNING: The following assert changes the file position.
+ # We must not depend on ths below or we'll fail in optimized mode.
+ assert read(8) == oid, (ofs, self.f.tell(), oid)
+
self._n_accesses += 1
self._trace(0x22, oid, tid, end_tid, ldata)
return data, tid
@@ -507,7 +511,8 @@
self.f.seek(ofs)
read = self.f.read
- assert read(1) == 'a', (ofs, self.f.tell(), oid, before_tid)
+ status = read(1)
+ assert status == 'a', (ofs, self.f.tell(), oid, before_tid)
size, saved_oid, saved_tid, end_tid, lver, ldata = unpack(
">I8s8s8sHI", read(34))
assert saved_oid == oid, (ofs, self.f.tell(), oid, saved_oid)
@@ -516,12 +521,15 @@
assert lver == 0, "Versions aren't supported"
data = read(ldata)
assert len(data) == ldata, (ofs, self.f.tell())
+
+ # WARNING: The following assert changes the file position.
+ # We must not depend on ths below or we'll fail in optimized mode.
assert read(8) == oid, (ofs, self.f.tell(), oid)
-
+
if end_tid < before_tid:
self._trace(0x24, oid, "", before_tid)
return None
-
+
self._n_accesses += 1
self._trace(0x26, oid, "", saved_tid)
return data, saved_tid, end_tid
@@ -543,7 +551,8 @@
if ofs:
seek(ofs)
read = self.f.read
- assert read(1) == 'a', (ofs, self.f.tell(), oid)
+ status = read(1)
+ assert status == 'a', (ofs, self.f.tell(), oid)
size, saved_oid, saved_tid, end_tid = unpack(
">I8s8s8s", read(28))
assert saved_oid == oid, (ofs, self.f.tell(), oid, saved_oid)
@@ -613,7 +622,7 @@
else:
self.current[oid] = ofs
self._trace(0x52, oid, start_tid, dlen=len(data))
-
+
self.currentofs += size
##
@@ -635,7 +644,7 @@
# to threading issues, that when applying a local
# invalidation after a store, that later invalidations from
# the server may already have arrived.
-
+
@locked
def invalidate(self, oid, tid, server_invalidation=True):
if tid is not None:
@@ -655,7 +664,8 @@
self.f.seek(ofs)
read = self.f.read
- assert read(1) == 'a', (ofs, self.f.tell(), oid)
+ status = read(1)
+ assert status == 'a', (ofs, self.f.tell(), oid)
size, saved_oid, saved_tid, end_tid = unpack(">I8s8s8s", read(28))
assert saved_oid == oid, (ofs, self.f.tell(), oid, saved_oid)
assert end_tid == z64, (ofs, self.f.tell(), oid)
@@ -685,7 +695,8 @@
self._lock.acquire()
try:
seek(ofs)
- assert read(1) == 'a', (ofs, self.f.tell(), oid)
+ status = read(1)
+ assert status == 'a', (ofs, self.f.tell(), oid)
size, saved_oid, tid, end_tid = unpack(">I8s8s8s", read(28))
assert saved_oid == oid, (ofs, self.f.tell(), oid, saved_oid)
assert end_tid == z64, (ofs, self.f.tell(), oid)
@@ -750,7 +761,7 @@
except:
print `tid`, `end_tid`
raise
-
+
self._trace = _trace
_trace(0x00)
More information about the Zodb-checkins
mailing list