[Zodb-checkins] SVN: ZODB/branches/3.3/src/ZEO/cache.py More
cleanup, and a new problem. Notable:
Tim Peters
tim.one at comcast.net
Tue Dec 21 18:48:05 EST 2004
Log message for revision 28680:
More cleanup, and a new problem. Notable:
Object.serialize_header(): Stopped stuffing the version string into this
notion of "a header". Couldn't see any reason for it, and it was
surprising.
ClientCache.invalidate(): Added some asserts to clarify intended
preconditions. Alas, my guess that it was intended that the passed-in
tid always be greater than the current tid turned out to trigger
errors. This gets complicated, and hasn't been resolved yet. The
problem is that the passed-in tid can be (in fact, always is) None
during cache verification. The code here *really* doesn't seem to
be expecting that, and the on-disk cache file is clearly left in a
wrong state (if we repopulated the cache from the disk file, the
object would not look invalidated any more, it would look current).
Dumped in a giant stack trace so I don't forget this; sent email to
Jeremy asking if he recalls what the real intent was.
Changed:
U ZODB/branches/3.3/src/ZEO/cache.py
-=-
Modified: ZODB/branches/3.3/src/ZEO/cache.py
===================================================================
--- ZODB/branches/3.3/src/ZEO/cache.py 2004-12-21 23:37:50 UTC (rev 28679)
+++ ZODB/branches/3.3/src/ZEO/cache.py 2004-12-21 23:48:05 UTC (rev 28680)
@@ -287,7 +287,6 @@
# @param oid object id
# @param version name of version to invalidate.
# @param tid the id of the transaction that wrote a new revision of oid
-
def invalidate(self, oid, version, tid):
if tid > self.fc.tid:
self.fc.settid(tid)
@@ -307,22 +306,72 @@
self._trace(0x10, oid, version, tid)
return
cur_tid = self.current.pop(oid)
+
+ # XXX. During checkDisconnectedAbort, tid shows up as None here
+ # sometimes.
+ #
+ #if not cur_tid < tid:
+ # print "OUCH1", cur_tid, tid
+ # import traceback
+ # traceback.print_stack()
+ #assert cur_tid < tid
+ #
+ # The stack trace. oid is 1, version '', tid None:
+ #
+ # File "C:\Python23\lib\threading.py", line 436, in __bootstrap
+ # self.run()
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\client.py", line 293, in run
+ # success = self.try_connecting(attempt_timeout)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\client.py", line 324, in try_connecting
+ # r = self._connect_wrappers(wrappers, deadline)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\client.py", line 385, in _connect_wrappers
+ # wrap.connect_procedure()
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\client.py", line 471, in connect_procedure
+ # self.test_connection()
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\client.py", line 495, in test_connection
+ # self.notify_client()
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\client.py", line 507, in notify_client
+ # self.client.notifyConnected(self.conn)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\ClientStorage.py", line 516, in notifyConnected
+ # self._wait_sync()
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\ClientStorage.py", line 370, in _wait_sync
+ # self._connection.pending(30)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\connection.py", line 546, in pending
+ # self.handle_read_event()
+ # File "C:\Python23\lib\asyncore.py", line 390, in handle_read_event
+ # self.handle_read()
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\smac.py", line 219, in handle_read
+ # self.message_input(msg)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\connection.py", line 244, in message_input
+ # self.handle_request(msgid, flags, name, args)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\zrpc\connection.py", line 269, in handle_request
+ # ret = meth(*args)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\tests\ConnectionTests.py", line 63, in endVerify
+ # ClientStorage.endVerify(self)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\ClientStorage.py", line 1093, in endVerify
+ # self._process_invalidations(InvalidationLogIterator(f))
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\ClientStorage.py", line 1074, in _process_invalidations
+ # self._cache.invalidate(oid, version, tid)
+ # File "C:\Code\ZODB3.3\build\lib.win32-2.3\ZEO\cache.py", line 313, in invalidate
+ # traceback.print_stack()
+
# XXX Want to fetch object without marking it as accessed
o = self.fc.access((oid, cur_tid))
+ assert o is not None
+ assert o.end_tid is None # i.e., o was current
if o is None:
- # XXX is this possible?
+ # XXX is this possible? (doubt it; added an assert just above)
return None
o.end_tid = tid
- self.fc.update(o)
+ self.fc.update(o) # record the new end_tid on disk
self._trace(0x1C, oid, version, tid)
L = self.noncurrent.setdefault(oid, [])
bisect.insort_left(L, (cur_tid, tid))
##
# Return the number of object revisions in the cache.
-
+ #
# XXX just return len(self.cache)?
-
def __len__(self):
n = len(self.current) + len(self.version)
if self.noncurrent:
@@ -488,25 +537,33 @@
if data is not None:
self.size = self.TOTAL_FIXED_SIZE + len(data) + len(version)
+ ##
+ # Return the fixed-sized serialization header as a string: pack end_tid,
+ # and the lengths of the .version and .data members.
def get_header(self):
- # Return just the fixed-size serialization header.
return struct.pack(self.fmt,
self.end_tid or z64,
len(self.version),
len(self.data))
+ ##
+ # Write the serialized representation of self to file f, at its current
+ # position.
def serialize(self, f):
- # Write standard form of Object to file f, at its current offset.
f.writelines([self.get_header(),
self.version,
self.data,
self.key[0]])
+ ##
+ # Write the fixed-size header for self, to file f at its current position.
+ # The only real use for this is when the current revision of an object
+ # in cache is invalidated. Then the end_tid field gets set to the tid
+ # of the transaction that caused the invalidation.
def serialize_header(self, f):
- # Write the fixed-sized serialization header, + the version.
- # Why is the version part of this?
- f.writelines([self.get_header(), self.version])
+ f.write(self.get_header())
+ ##
# fromFile is a class constructor, unserializing an Object from the
# current position in file f. Exclusive access to f for the duration
# is assumed. The key is a (oid, start_tid) pair, and the oid must
@@ -955,7 +1012,9 @@
# Update on-disk representation of Object obj.
#
# This method should be called when the object header is modified.
- # obj must be in the cache.
+ # obj must be in the cache. The only real use for this is during
+ # invalidation, to set the end_tid field on a revision that was current
+ # (and so had an end_tid of None, but no longer does).
def update(self, obj):
e = self.key2entry[obj.key]
self.f.seek(e.offset + OBJECT_HEADER_SIZE)
More information about the Zodb-checkins
mailing list