[Zodb-checkins] CVS: ZODB3/ZEO - ClientStorage.py:1.58
Guido van Rossum
guido@python.org
Thu, 12 Sep 2002 00:30:20 -0400
Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv18872
Modified Files:
ClientStorage.py
Log Message:
First part of changes to fall back to a read-only connection when a
read-write connection is not available. This refactors
ClientStorage.notifyConnected() into two functions, testConnection()
and notifyConnected(). testConnection creates the RPC stub and calls
the register() method; it returns the stub plus a flag indicating
whether this connection was preferred or sub-optimal. If the
register() method raises ReadOnlyError, and the new option
read_only_fallback was true on the ClientStorage constructor, it is
retried with its read_only argument set to 1, and the stub is returned
with the sub-optimal flag. notifyConnected() now receives the stub
returned by testConnection(), and starts the verification as before.
XXX The read_only_fallback feature is not yet tested.
XXX More work is needed; when a suboptimal connection is used, the
ConnectThread must stay around trying to get a preferred connection,
and then it must switch connections on the ClientStorage (how???).
=== ZODB3/ZEO/ClientStorage.py 1.57 => 1.58 ===
--- ZODB3/ZEO/ClientStorage.py:1.57 Wed Sep 11 13:36:39 2002
+++ ZODB3/ZEO/ClientStorage.py Thu Sep 12 00:30:19 2002
@@ -74,12 +74,13 @@
def __init__(self, addr, storage='1', cache_size=20000000,
name='', client=None, var=None,
min_disconnect_poll=5, max_disconnect_poll=300,
- wait=0, read_only=0):
+ wait=0, read_only=0, read_only_fallback=0):
self._addr = addr # For tests
self._server = disconnected_stub
self._is_read_only = read_only
self._storage = storage
+ self._read_only_fallback = read_only_fallback
self._info = {'length': 0, 'size': 0, 'name': 'ZEO Client',
'supportsUndo':0, 'supportsVersions': 0,
@@ -175,21 +176,41 @@
"""Handle any pending invalidation messages."""
self._server._update()
- def notifyConnected(self, conn):
- log2(INFO, "Connected to storage via %s" % repr(conn))
-
- # check the protocol version here?
+ def testConnection(self, conn):
+ """Return a pair (stub, preferred).
+ Where:
+ - stub is an RPC stub
+ - preferred is: 1 if the connection is an optimal match,
+ 0 if it is a suboptimal but acceptable match
+ It can also raise DisconnectedError or ReadOnlyError.
+
+ This is called by ConnectionManager to decide which connection
+ to use in case there are multiple, and some are read-only and
+ others are read-write.
+ """
+ log2(INFO, "Testing connection %r" % conn)
+ # XXX Check the protocol version here?
stub = ServerStub.StorageServer(conn)
-
+ try:
+ stub.register(str(self._storage), self._is_read_only)
+ return (stub, 1)
+ except POSException.ReadOnlyError:
+ if not self._read_only_fallback:
+ raise
+ stub.register(str(self._storage), read_only=1)
+ return (stub, 0)
+
+ def notifyConnected(self, stub):
+ """Start using the given RPC stub.
+
+ This is called by ConnectionManager after it has decided which
+ connection should be used.
+ """
self._oids = []
-
- stub.register(str(self._storage), self._is_read_only)
self._info.update(stub.get_info())
self.verify_cache(stub)
- # Don't make the server available to clients until after
- # validating the cache
# XXX The stub should be saved here and set in end() below.
self._server = stub