[Zodb-checkins] CVS: ZODB3/ZEO/zrpc - client.py:1.10
Guido van Rossum
guido@python.org
Thu, 12 Sep 2002 00:30:21 -0400
Update of /cvs-repository/ZODB3/ZEO/zrpc
In directory cvs.zope.org:/tmp/cvs-serv18872/zrpc
Modified Files:
client.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/zrpc/client.py 1.9 => 1.10 ===
--- ZODB3/ZEO/zrpc/client.py:1.9 Thu Sep 12 00:02:18 2002
+++ ZODB3/ZEO/zrpc/client.py Thu Sep 12 00:30:19 2002
@@ -215,6 +215,7 @@
self.tmax = tmax
self.stopped = 0
self.one_attempt = threading.Event()
+ self.fallback = None
# A ConnectThread keeps track of whether it has finished a
# call to attempt_connects(). This allows the
# ConnectionManager to make an attempt to connect right away,
@@ -293,7 +294,21 @@
if ok:
del self.sockets[s] # don't close the newly connected socket
self.close_sockets()
- return ok
+ return 1
+ if self.fallback:
+ (c, stub) = self.fallback
+ self.fallback = None
+ try:
+ self.client.notifyConnected(stub)
+ except:
+ log("error in notifyConnected (%r)" % addr,
+ level=zLOG.ERROR, error=sys.exc_info())
+ c.close()
+ return 0
+ else:
+ self.mgr.connect_done(c)
+ return 1
+ return 0
def try_connect(self, s):
"""Call s.connect_ex(addr); return true iff connection succeeds.
@@ -364,13 +379,25 @@
# okay.
c = ManagedConnection(s, addr, self.client, self.mgr)
try:
- self.client.notifyConnected(c)
+ (stub, preferred) = self.client.testConnection(c)
except:
- log("error connecting to server: %s" % str(addr),
+ log("error in testConnection (%r)" % addr,
level=zLOG.ERROR, error=sys.exc_info())
c.close()
# Closing the ZRPC connection will eventually close the
# socket, somewhere in asyncore.
return 0
- self.mgr.connect_done(c)
- return 1
+ if preferred:
+ try:
+ self.client.notifyConnected(stub)
+ except:
+ log("error in notifyConnected (%r)" % addr,
+ level=zLOG.ERROR, error=sys.exc_info())
+ c.close()
+ return 0
+ else:
+ self.mgr.connect_done(c)
+ return 1
+ if self.fallback is None:
+ self.fallback = (c, stub)
+ return 0