[Zodb-checkins] CVS: ZODB3/ZEO - ClientStorage.py:1.73.2.4.2.1
Jeremy Hylton
jeremy@zope.com
Fri, 1 Nov 2002 14:17:25 -0500
Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv20135/ZEO
Modified Files:
Tag: ZODB3-deadlock-debug-branch
ClientStorage.py
Log Message:
Implement sortKey() for ClientStorage.
The sortKey is the address of the current storage server. Two
wrinkles of interest:
- A single client can connect to multiple servers, so its sortKey()
can change.
- If different clients use different names (e.g. one uses hostname and
one uses IP address), we could get different sortKeys. This config
should be avoided, but the code tries to get a canonical name just
in case.
=== ZODB3/ZEO/ClientStorage.py 1.73.2.4 => 1.73.2.4.2.1 ===
--- ZODB3/ZEO/ClientStorage.py:1.73.2.4 Wed Oct 16 17:44:05 2002
+++ ZODB3/ZEO/ClientStorage.py Fri Nov 1 14:17:24 2002
@@ -28,9 +28,11 @@
import cPickle
import os
+import socket
import tempfile
import threading
import time
+import types
from ZEO import ClientCache, ServerStub
from ZEO.TransactionBuffer import TransactionBuffer
@@ -204,6 +206,8 @@
self._storage = storage
self._read_only_fallback = read_only_fallback
self._connection = None
+ # _server_addr is used by sortKey()
+ self._server_addr = None
self._info = {'length': 0, 'size': 0, 'name': 'ZEO Client',
'supportsUndo':0, 'supportsVersions': 0,
@@ -339,6 +343,7 @@
log2(INFO, "Reconnected to storage")
else:
log2(INFO, "Connected to storage")
+ self.set_server_addr(conn.get_addr())
stub = self.StorageServerStubClass(conn)
self._oids = []
self._info.update(stub.get_info())
@@ -349,6 +354,33 @@
self._connection.close()
self._connection = conn
self._server = stub
+
+ def set_server_addr(self, addr):
+ # Normalize server address and convert to string
+ if isinstance(addr, types.StringType):
+ self._server_addr = addr
+ else:
+ assert isinstance(addr, types.TupleType)
+ # If the server is on a remote host, we need to guarantee
+ # that all clients used the same name for the server. If
+ # they don't, the sortKey() may be different for each client.
+ # The best solution seems to be the official name reported
+ # by gethostbyaddr().
+ host = addr[0]
+ try:
+ canonical, aliases, addrs = socket.gethostbyaddr(host)
+ except socket.error, err:
+ log2(INFO, "Error resoving host: %s (%s)" % (host, err))
+ canonical = host
+ self._server_addr = str((canonical, addr[1]))
+
+ def sortKey(self):
+ # If the client isn't connected to anything, it can't have a
+ # valid sortKey(). Raise an error to stop the transaction early.
+ if self._server_addr is None:
+ raise ClientDisconnected
+ else:
+ return self._server_addr
def verify_cache(self, server):
"""Internal routine called to verify the cache."""