[Zodb-checkins] CVS: ZODB3/ZEO - StorageServer.py:1.70

Guido van Rossum guido@python.org
Thu, 26 Sep 2002 13:01:35 -0400


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

Modified Files:
	StorageServer.py 
Log Message:
Add a read_only attribute to the ZEOStorage instance.  This is
initialized from the StorageServer's read_only attribute, and later if
the client registers in read_only mode, it may be set even if was off
initially.  This attribute is tested by all write-ish operations.


=== ZODB3/ZEO/StorageServer.py 1.69 => 1.70 ===
--- ZODB3/ZEO/StorageServer.py:1.69	Fri Sep 20 15:03:48 2002
+++ ZODB3/ZEO/StorageServer.py	Thu Sep 26 13:01:35 2002
@@ -74,7 +74,8 @@
                                      reuse_addr=1)
 
     def new_connection(self, sock, addr):
-        c = ManagedServerConnection(sock, addr, ZEOStorage(self), self)
+        z = ZEOStorage(self, self.read_only)
+        c = ManagedServerConnection(sock, addr, z, self)
         log("new connection %s: %s" % (addr, `c`))
         return c
 
@@ -117,12 +118,13 @@
 class ZEOStorage:
     """Proxy to underlying storage for a single remote client."""
 
-    def __init__(self, server):
+    def __init__(self, server, read_only=0):
         self.server = server
         self.client = None
         self.storage = None
         self.storage_id = "uninitialized"
         self.transaction = None
+        self.read_only = read_only
 
     def notifyConnected(self, conn):
         self.client = ClientStub.ClientStorage(conn)
@@ -162,6 +164,8 @@
         self.modifiedInVersion = self.storage.modifiedInVersion
 
     def check_tid(self, tid, exc=None):
+        if self.read_only:
+            raise ReadOnlyError()
         caller = sys._getframe().f_back.f_code.co_name
         if self.transaction is None:
             self.log("no current transaction: %s()" % caller, zLOG.PROBLEM)
@@ -193,9 +197,10 @@
             self.log("unknown storage_id: %s" % storage_id)
             raise ValueError, "unknown storage: %s" % storage_id
 
-        if not read_only and (self.server.read_only or storage.isReadOnly()):
+        if not read_only and (self.read_only or storage.isReadOnly()):
             raise ReadOnlyError()
 
+        self.read_only = self.read_only or read_only
         self.storage_id = storage_id
         self.storage = storage
         self.setup_delegation()
@@ -250,6 +255,7 @@
         self.client.endVerify()
 
     def pack(self, time, wait=1):
+        # Yes, you can pack a read-only server or storage!
         if wait:
             return run_in_thread(self.pack_impl, time)
         else:
@@ -268,11 +274,15 @@
 
     def new_oids(self, n=100):
         """Return a sequence of n new oids, where n defaults to 100"""
+        if self.read_only:
+            raise ReadOnlyError()
         if n <= 0:
             n = 1
         return [self.storage.new_oid() for i in range(n)]
 
     def undo(self, transaction_id):
+        if self.read_only:
+            raise ReadOnlyError()
         oids = self.storage.undo(transaction_id)
         if oids:
             self.server.invalidate(self, self.storage_id,
@@ -289,6 +299,8 @@
         return run_in_thread(self.storage.undoLog, first, last)
 
     def tpc_begin(self, id, user, description, ext, tid, status):
+        if self.read_only:
+            raise ReadOnlyError()
         if self.transaction is not None:
             if self.transaction.id == id:
                 self.log("duplicate tpc_begin(%s)" % repr(id))