[Zodb-checkins] CVS: ZODB3/ZEO/zrpc - client.py:1.13

Guido van Rossum guido@python.org
Fri, 13 Sep 2002 17:11:02 -0400


Update of /cvs-repository/ZODB3/ZEO/zrpc
In directory cvs.zope.org:/tmp/cvs-serv10148

Modified Files:
	client.py 
Log Message:
Major refactoring of the ConnectThread, to support the
read_only_fallback option of ClientStorage.

Unfortunately, this still doesn't work completely; as shown by some
disabled tests that I'll check in shortly, the reconnect feature is
still broken.  But it's weekend time, and I need a checkpoint to keep
my own sanity.


=== ZODB3/ZEO/zrpc/client.py 1.12 => 1.13 === (408/508 lines abridged)
--- ZODB3/ZEO/zrpc/client.py:1.12	Thu Sep 12 17:43:43 2002
+++ ZODB3/ZEO/zrpc/client.py	Fri Sep 13 17:11:02 2002
@@ -22,6 +22,8 @@
 import ThreadedAsync
 import zLOG
 
+from ZODB.POSException import ReadOnlyError
+
 from ZEO.zrpc.log import log
 from ZEO.zrpc.trigger import trigger
 from ZEO.zrpc.connection import ManagedConnection
@@ -86,14 +88,14 @@
         self.thread_lock.acquire()
         try:
             t = self.thread
-            if t is not None:
-                t.stop()
         finally:
             self.thread_lock.release()
         if t is not None:
+            log("CM.close(): stopping and joining thread")
+            t.stop()
             t.join(30)
             if t.isAlive():
-                log("ConnectionManager.close(): self.thread.join() timed out")
+                log("CM.close(): self.thread.join() timed out")
         if self.connection:
             self.connection.close()
         if self.trigger is not None:
@@ -112,7 +114,9 @@
 
         # XXX need each connection started with async==0 to have a
         # callback
+        log("CM.set_async(%s)" % repr(map))
         if not self.closed and self.trigger is None:
+            log("CM.set_async(): first call")
             self.trigger = trigger()
             self.thr_async = 1 # XXX needs to be set on the Connection
 
@@ -146,7 +150,7 @@
         try:
             t = self.thread
             if t is None:
-                log("starting thread to connect to server")
+                log("CM.connect(): starting ConnectThread")
                 self.thread = t = ConnectThread(self, self.client,
                                                 self.addrlist,
                                                 self.tmin, self.tmax)
@@ -156,21 +160,22 @@
         if sync:

[-=- -=- -=- 408 lines omitted -=- -=- -=-]

+        """
+        if self.mgr.connected:
+            assert self.preferred
+            log("CW: reconnecting client to preferred stub")
+            self.mgr.notify_closed()
         try:
-            (stub, preferred) = self.client.testConnection(c)
+            self.client.notifyConnected(self.stub)
         except:
-            log("error in testConnection (%r)" % (addr,),
+            log("CW: error in notifyConnected (%s)" % repr(self.addr),
                 level=zLOG.ERROR, error=sys.exc_info())
-            c.close()
+            self.close()
+            return
+        self.state = "notified"
+        self.mgr.connect_done(self.conn, self.preferred)
+
+    def close(self):
+        """Close the socket and reset everything."""
+        self.state = "closed"
+        self.stub = self.mgr = self.client = None
+        self.preferred = 0
+        if self.conn is not None:
             # Closing the ZRPC connection will eventually close the
             # socket, somewhere in asyncore.
-            return 0
-        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
+            # XXX Why do we care? --Guido
+            self.conn.close()
+            self.conn = None
+        if self.sock is not None:
+            self.sock.close()
+            self.sock = None
+
+    def fileno(self):
+        return self.sock.fileno()