[Zodb-checkins] SVN: ZODB/trunk/src/ZEO/ Changed the dropped-cache event to a StaleCache event that's published
Jim Fulton
jim at zope.com
Tue Nov 18 21:30:18 EST 2008
Log message for revision 93124:
Changed the dropped-cache event to a StaleCache event that's published
whenever the cache is stale. This is generated before dropping a cache
and starting cold so that an application can take more drastic
measures. The stale-cache event also now has a storage attribute with
the storage that has a stale cache.
Changed:
U ZODB/trunk/src/ZEO/ClientStorage.py
U ZODB/trunk/src/ZEO/interfaces.py
U ZODB/trunk/src/ZEO/tests/drop_cache_rather_than_verify.txt
-=-
Modified: ZODB/trunk/src/ZEO/ClientStorage.py
===================================================================
--- ZODB/trunk/src/ZEO/ClientStorage.py 2008-11-19 02:15:37 UTC (rev 93123)
+++ ZODB/trunk/src/ZEO/ClientStorage.py 2008-11-19 02:30:17 UTC (rev 93124)
@@ -1254,6 +1254,8 @@
elif ltid and ltid != utils.z64:
self._cache.setLastTid(ltid)
+ zope.event.notify(ZEO.interfaces.StaleCache(self))
+
# From this point on, we do not have complete information about
# the missed transactions. The reason is that cache
# verification only checks objects in the client cache and
@@ -1265,7 +1267,6 @@
if self._cache and self._drop_cache_rather_verify:
logger.critical("%s dropping stale cache", self.__name__)
- zope.event.notify(ZEO.interfaces.CacheDroppedEvent())
self._cache.clear()
if ltid:
self._cache.setLastTid(ltid)
Modified: ZODB/trunk/src/ZEO/interfaces.py
===================================================================
--- ZODB/trunk/src/ZEO/interfaces.py 2008-11-19 02:15:37 UTC (rev 93123)
+++ ZODB/trunk/src/ZEO/interfaces.py 2008-11-19 02:30:17 UTC (rev 93124)
@@ -14,10 +14,13 @@
import zope.interface
-class CacheDroppedEvent(object):
- """A ZEO Cache file was dropped to avoid verification
+class StaleCache(object):
+ """A ZEO cache is stale and requires verification.
"""
+ def __init__(self, storage):
+ self.storage = storage
+
class IServeable(zope.interface.Interface):
"""Interface provided by storages that can be served by ZEO
"""
Modified: ZODB/trunk/src/ZEO/tests/drop_cache_rather_than_verify.txt
===================================================================
--- ZODB/trunk/src/ZEO/tests/drop_cache_rather_than_verify.txt 2008-11-19 02:15:37 UTC (rev 93123)
+++ ZODB/trunk/src/ZEO/tests/drop_cache_rather_than_verify.txt 2008-11-19 02:30:17 UTC (rev 93124)
@@ -6,9 +6,13 @@
might be necessary, but cache verification can be very hard on the
storage server.
+When verification is needed, a ZEO.interfaces.StaleCache event is
+published. Applications may handle this event to perform actions such
+as exiting the process to avoid a cold restart.
+
ClientStorage provides an option to drop it's cache rather than doing
verification. When this option is used, and verification would be
-necessary, ClientStorage:
+necessary, after publishing the event, ClientStorage:
- Invalidates all object caches
@@ -17,8 +21,6 @@
- Logs a CRITICAL message.
-- Publishes a ZEO.interfaces.CacheDroppedEvent event.
-
Here's an example that shows that this is actually what happens.
Start a server, create a cient to it and commit some data
@@ -58,8 +60,15 @@
>>> handler = zope.testing.loggingsupport.InstalledHandler(
... 'ZEO.ClientStorage', level=logging.ERROR)
>>> events = []
- >>> zope.event.subscribers.append(events.append)
+ >>> def event_handler(e):
+ ... events.append((
+ ... len(e.storage._cache), str(handler), e.__class__.__name__))
+ >>> zope.event.subscribers.append(event_handler)
+Note that the event handler is saving away the length of the cache and
+the state of the log handler. We'll use this to show that the event
+is generated before the cache is dropped or the message is logged.
+
Now, we'll restart the server on the original address:
>>> _, admin = start_server(zeo_conf=dict(invalidation_queue_size=1),
@@ -67,6 +76,19 @@
>>> wait_connected(db.storage)
Now, let's verify our assertions above:
+
+- Publishes a stale-cache event.
+
+ >>> for e in events:
+ ... print e
+ (3, '', 'StaleCache')
+
+ Note that the length of the cache when the event handler was
+ called waa non-zero. This is because the cache wasn't cleared
+ yet. Similarly, the dropping-cache message hasn't been logged
+ yet.
+
+ >>> del events[:]
- Drops or clears it's client cache. (The end result is that the cache
is working but empty.)
@@ -87,14 +109,6 @@
>>> handler.clear()
-- Publishes a cache-dropped event.
-
- >>> for e in events:
- ... print e.__class__.__name__
- CacheDroppedEvent
-
- >>> del events[:]
-
If we access the root object, it'll be loaded from the server:
>>> conn.root()[1].x
@@ -130,6 +144,14 @@
(When a database is created, it checks to make sure the root object is
in the database, which is why we get 1, rather than 0 objects in the cache.)
+- Publishes a stake-cache event.
+
+ >>> for e in events:
+ ... print e
+ (2, '', 'StaleCache')
+
+ >>> del events[:]
+
- Logs a CRITICAL message.
>>> print handler
@@ -138,16 +160,57 @@
>>> handler.clear()
-- Publishes a cache-dropped event.
+If we access the root object, it'll be loaded from the server:
- >>> for e in events:
- ... print e.__class__.__name__
- CacheDroppedEvent
+ >>> conn = db.open()
+ >>> conn.root()[1].x
+ 11
-If we access the root object, it'll be loaded from the server:
+Finally, let's look at what happens without the
+drop_cache_rather_verify option:
+
+ >>> db.close()
+ >>> db = ZEO.DB(addr, client='cache')
+ >>> wait_connected(db.storage)
>>> conn = db.open()
>>> conn.root()[1].x
11
+ >>> conn.root()[2] = conn.root().__class__()
+ >>> transaction.commit()
+ >>> len(db.storage._cache)
+ 4
+ >>> stop_server(admin)
+ >>> addr2, admin = start_server(keep=1)
+ >>> db2 = ZEO.DB(addr2)
+ >>> wait_connected(db2.storage)
+ >>> conn2 = db2.open()
+ >>> for i in range(5):
+ ... conn2.root()[1].x += 1
+ ... transaction.commit()
+ >>> db2.close()
+ >>> stop_server(admin)
+
+ >>> _, admin = start_server(zeo_conf=dict(invalidation_queue_size=1),
+ ... addr=addr)
+ >>> wait_connected(db.storage)
+
+ >>> for e in events:
+ ... print e
+ (4, '', 'StaleCache')
+
+ >>> print handler
+ <BLANKLINE>
+
+ >>> len(db.storage._cache)
+ 3
+
+Here we see the cache wasn't dropped, although one of the records was
+invalidated during verification.
+
+.. Cleanup
+
>>> db.close()
+ >>> handler.uninstall()
+ >>> zope.event.subscribers.remove(event_handler)
More information about the Zodb-checkins
mailing list