[Zope3-checkins] CVS: Zope3/src/zodb/zeo - client.py:1.3.4.1 server.py:1.4.4.1
Jeremy Hylton
jeremy@zope.com
Tue, 4 Feb 2003 17:54:49 -0500
Update of /cvs-repository/Zope3/src/zodb/zeo
In directory cvs.zope.org:/tmp/cvs-serv6570/src/zodb/zeo
Modified Files:
Tag: storage-interface-branch
client.py server.py
Log Message:
Refactor storage interfaces.
Move a bunch of exceptions related to storages from zodb.interfaces to
zodb.storages.interfaces.
Add __implements__ statements in all the concrete storage classes.
Add a simple (good?) mechanism to propagate __implements__ values from
a ZEO storage to its clients.
Remove all use of supportsXXX() methods in favor of
ISomeInterface.isImplementedBy().
=== Zope3/src/zodb/zeo/client.py 1.3 => 1.3.4.1 ===
--- Zope3/src/zodb/zeo/client.py:1.3 Fri Jan 24 18:20:49 2003
+++ Zope3/src/zodb/zeo/client.py Tue Feb 4 17:54:17 2003
@@ -41,7 +41,7 @@
from zodb.zeo.tbuf import TransactionBuffer
from zodb.zeo.zrpc.client import ConnectionManager
-from zodb import interfaces
+from zodb.storage.interfaces import *
from zodb.timestamp import TimeStamp
try:
@@ -49,7 +49,7 @@
except ImportError:
ResolvedSerial = 'rs'
-class ClientStorageError(interfaces.StorageError):
+class ClientStorageError(StorageError):
"""An error occured in the ZEO Client Storage."""
class UnrecognizedResult(ClientStorageError):
@@ -105,6 +105,13 @@
ConnectionManagerClass = ConnectionManager
StorageServerStubClass = stubs.StorageServer
+ # The exact storage interfaces depend on the server that the client
+ # connects to. We know that every storage must implement IStorage,
+ # but once connected we may change the instance's __implements__
+ # to reflect features available on the storage.
+
+ __implements__ = IStorage
+
def __init__(self, addr, storage='1', cache_size=20 * MB,
name='', client=None, debug=0, var=None,
min_disconnect_poll=5, max_disconnect_poll=300,
@@ -210,10 +217,8 @@
# _server_addr is used by sortKey()
self._server_addr = None
- self._info = {'length': 0, 'size': 0, 'name': 'ZEO Client',
- 'supportsUndo':0, 'supportsVersions': 0,
- 'supportsTransactionalUndo': 0}
-
+ self._info = {'length': 0, 'size': 0, 'name': 'ZEO Client'}
+
self._tbuf = self.TransactionBufferClass()
self._db = None
@@ -325,7 +330,7 @@
try:
stub.register(str(self._storage), self._is_read_only)
return 1
- except interfaces.ReadOnlyError:
+ except ReadOnlyError:
if not self._read_only_fallback:
raise
self.logger.warn(
@@ -347,6 +352,7 @@
stub = self.StorageServerStubClass(conn)
self._oids = []
self._info.update(stub.get_info())
+ self.update_interfaces()
self.verify_cache(stub)
# XXX The stub should be saved here and set in endVerify() below.
@@ -355,6 +361,16 @@
self._connection = conn
self._server = stub
+ def update_interfaces(self):
+ # Update instance's __implements__ based on the server.
+ L = [IStorage]
+ for name in self._info.get("implements", ()):
+ if name == "IUndoStorage":
+ L.append(IUndoStorage)
+ elif name == "IVersionStorage":
+ L.append(IVersionStorage)
+ self.__implements__ = tuple(L)
+
def set_server_addr(self, addr):
# Normalize server address and convert to string
if isinstance(addr, types.StringType):
@@ -433,18 +449,6 @@
"""
return self._info['extensionMethods']
- def supportsUndo(self):
- """Storage API: return whether we support undo."""
- return self._info['supportsUndo']
-
- def supportsVersions(self):
- """Storage API: return whether we support versions."""
- return self._info['supportsVersions']
-
- def supportsTransactionalUndo(self):
- """Storage API: return whether we support transactional undo."""
- return self._info['supportsTransactionalUndo']
-
def isReadOnly(self):
"""Storage API: return whether we are in read-only mode.
@@ -464,10 +468,9 @@
def _check_trans(self, trans):
"""Internal helper to check a transaction argument for sanity."""
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
if self._transaction is not trans:
- raise interfaces.StorageTransactionError(self._transaction,
- trans)
+ raise StorageTransactionError(self._transaction, trans)
def abortVersion(self, version, transaction):
"""Storage API: clear any changes made by the given version."""
@@ -553,7 +556,7 @@
def new_oid(self):
"""Storage API: return a new object identifier."""
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
# avoid multiple oid requests to server at the same time
self._oid_lock.acquire()
try:
@@ -613,7 +616,7 @@
def tpc_begin(self, txn, tid=None, status=' '):
"""Storage API: begin a transaction."""
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
self._tpc_cond.acquire()
while self._transaction is not None:
# It is allowable for a client to call two tpc_begins in a
@@ -739,7 +742,7 @@
def undo(self, transaction_id):
"""Storage API: undo a transaction, writing directly to the storage."""
if self._is_read_only:
- raise interfaces.ReadOnlyError()
+ raise ReadOnlyError()
# XXX what are the sync issues here?
oids = self._server.undo(transaction_id)
for oid in oids:
=== Zope3/src/zodb/zeo/server.py 1.4 => 1.4.4.1 ===
--- Zope3/src/zodb/zeo/server.py:1.4 Fri Jan 24 18:20:49 2003
+++ Zope3/src/zodb/zeo/server.py Tue Feb 4 17:54:17 2003
@@ -34,8 +34,10 @@
from zodb.zeo.zrpc.connection import ManagedServerConnection, Delay, MTDelay
from zodb.ztransaction import Transaction
-from zodb.interfaces import StorageError, StorageTransactionError
-from zodb.interfaces import TransactionError, ReadOnlyError
+from zodb.interfaces import TransactionError
+from zodb.storage.interfaces import *
+
+from zope.interface.implements import objectImplements
class StorageServerError(StorageError):
"""Error reported when an unpickleable exception is raised."""
@@ -241,7 +243,6 @@
self.setVersion = self.storage.setVersion
self.versionEmpty = self.storage.versionEmpty
self.versions = self.storage.versions
- self.history = self.storage.history
self.load = self.storage.load
self.loadSerial = self.storage.loadSerial
self.modifiedInVersion = self.storage.modifiedInVersion
@@ -302,11 +303,10 @@
self.server.register_connection(storage_id, self)
def get_info(self):
- return {'name': self.storage.getName(),
- 'supportsVersions': self.storage.supportsVersions(),
- 'supportsTransactionalUndo':
- self.storage.supportsTransactionalUndo(),
- 'extensionMethods': self.getExtensionMethods(),
+ return {"name": self.storage.getName(),
+ "implements": [iface.__name__
+ for iface in objectImplements(self.storage)],
+ "extensionMethods": self.getExtensionMethods(),
}
def getExtensionMethods(self):