• Guido van Rossum's avatar
    I set out making wait=1 work for fallback connections, i.e. the · 24afe7ac
    Guido van Rossum authored
    ClientStorage constructor called with both wait=1 and
    read_only_fallback=1 should return, indicating its readiness, when a
    read-only connection was made.  This is done by calling
    connect(sync=1).  Previously this waited for the ConnectThread to
    finish, but that thread doesn't finish until it's made a read-write
    connection, so a different mechanism is needed.
    
    I ended up doing a major overhaul of the interfaces between
    ClientStorage, ConnectionManager, ConnectThread/ConnectWrapper, and
    even ManagedConnection.  Changes:
    
    ClientStorage.py:
    
      ClientStorage:
    
      - testConnection() now returns just the preferred flag; stubs are
        cheap and I like to have the notifyConnected() signature be the
        same for clients and servers.
    
      - notifyConnected() now takes a connection (to match the signature
        of this method in StorageServer), and creates a new stub.  It also
        takes care of the reconnect business if the client was already
        connected, rather than the ClientManager.  It stores the
        connection as self._connection so it can close the previous one.
        This is also reset by notifyDisconnected().
    
    zrpc/client.py:
    
      ConnectionManager:
    
      - Changed self.thread_lock into a condition variable.  It now also
        protects self.connection.  The condition is notified when
        self.connection is set to a non-None value in connect_done();
        connect(sync=1) waits for it.  The self.connected variable is no
        more; we test "self.connection is not None" instead.
    
      - Tried to made close() reentrant.  (There's a trick: you can't set
        self.connection to None, conn.close() ends up calling close_conn()
        which does this.)
    
      - Renamed notify_closed() to close_conn(), for symmetry with the
        StorageServer API.
    
      - Added an is_connected() method so ConnectThread.try_connect()
        doesn't have to dig inside the manager's guts to find out if the
        manager is connected (important for the disposition of fallback
        wrappers).
    
      ConnectThread and ConnectWrapper:
    
      - Follow above changes in the ClientStorage and ConnectionManager
        APIs: don't close the manager's connection when reconnecting, but
        leave that up to notifyConnected(); ConnectWrapper no longer
        manages the stub.
    
      - ConnectWrapper sets self.sock to None once it's created a
        ManagedConnection -- from there on the connection is is charge of
        closing the socket.
    
    zrpc/connection.py:
    
      ManagedServerConnection:
    
      - Changed the order in which close() calls things; super_close()
        should be last.
    
      ManagedConnection:
    
      - Ditto, and call the manager's close_conn() instead of
        notify_closed().
    
    tests/testZEO.py:
    
      - In checkReconnectSwitch(), we can now open the client storage with
        wait=1 and read_only_fallback=1.
    24afe7ac
ClientStorage.py 20.4 KB