[Checkins] SVN: gocept.zeoraid/trunk/src/gocept/zeoraid/ Reloading now uses the config file obtained from ZEO. This means that running

Thomas Lotze tl at gocept.com
Thu Jan 8 06:57:09 EST 2009


Log message for revision 94616:
  Reloading now uses the config file obtained from ZEO. This means that running
  the RAID storage within a ZEO server is required for reloading the config.
  

Changed:
  U   gocept.zeoraid/trunk/src/gocept/zeoraid/datatypes.py
  U   gocept.zeoraid/trunk/src/gocept/zeoraid/interfaces.py
  U   gocept.zeoraid/trunk/src/gocept/zeoraid/storage.py
  U   gocept.zeoraid/trunk/src/gocept/zeoraid/tests/test_basics.py

-=-
Modified: gocept.zeoraid/trunk/src/gocept/zeoraid/datatypes.py
===================================================================
--- gocept.zeoraid/trunk/src/gocept/zeoraid/datatypes.py	2009-01-08 10:12:47 UTC (rev 94615)
+++ gocept.zeoraid/trunk/src/gocept/zeoraid/datatypes.py	2009-01-08 11:57:09 UTC (rev 94616)
@@ -14,6 +14,8 @@
 """ZConfig storage type definitions.
 """
 
+import inspect
+
 import ZODB.config
 import gocept.zeoraid.storage
 
@@ -21,9 +23,17 @@
 class Storage(ZODB.config.BaseConfig):
 
     def open(self):
+        parent_frame = inspect.stack()[1][0]
+        parent_self = parent_frame.f_locals.get('self')
+        if parent_self and parent_self.__class__.__name__ == 'ZEOServer':
+            zeo = parent_self
+        else:
+            zeo = None
+
         return gocept.zeoraid.storage.RAIDStorage(
             self.name,
             self.config.storages,
             blob_dir=self.config.blob_dir,
             read_only=self.config.read_only,
-            shared_blob_dir=self.config.shared_blob_dir)
+            shared_blob_dir=self.config.shared_blob_dir,
+            zeo=zeo)

Modified: gocept.zeoraid/trunk/src/gocept/zeoraid/interfaces.py
===================================================================
--- gocept.zeoraid/trunk/src/gocept/zeoraid/interfaces.py	2009-01-08 10:12:47 UTC (rev 94615)
+++ gocept.zeoraid/trunk/src/gocept/zeoraid/interfaces.py	2009-01-08 11:57:09 UTC (rev 94616)
@@ -42,7 +42,10 @@
     def raid_recover(name):
         pass
 
+    def raid_reload():
+        pass
 
+
 class ITransactionInspection(zope.interface.Interface):
     """Storage API extension to allow inspecting historical transactions."""
 

Modified: gocept.zeoraid/trunk/src/gocept/zeoraid/storage.py
===================================================================
--- gocept.zeoraid/trunk/src/gocept/zeoraid/storage.py	2009-01-08 10:12:47 UTC (rev 94615)
+++ gocept.zeoraid/trunk/src/gocept/zeoraid/storage.py	2009-01-08 11:57:09 UTC (rev 94616)
@@ -120,10 +120,11 @@
     timeout = 60
 
     def __init__(self, name, openers, read_only=False, blob_dir=None,
-                 shared_blob_dir=False):
+                 shared_blob_dir=False, zeo=None):
         self.__name__ = name
         self.read_only = read_only
         self.shared_blob_dir = shared_blob_dir
+        self.zeo = zeo
         self.storages = {}
         self._threads = set()
         # Temporary files and directories that should be removed at the end of
@@ -595,13 +596,18 @@
         return 'recovering %r' % (name,)
 
     @ensure_open_storage
-    def raid_reload(self, path):
-        s = ""
+    def raid_reload(self):
+        if not self.zeo:
+            raise RuntimeError(
+                'Cannot reload config without running inside ZEO.')
+
         options = ZEOOptions()
-        options.realize(['-C',path])
+        options.realize(['-C', self.zeo.options.configfile])
         new_storages = dict([(o.name,o) for o in options.storages[0].config.storages])
         storages_to_add = [(name, opener) for name, opener in new_storages.items() if name not in self.openers]
         storages_to_remove = [(name, opener) for name, opener in self.openers.items() if name not in new_storages]
+
+        s = ""
         for name, opener in storages_to_remove:
             self.raid_disable(name)
             s += "removed %s\n" % name

Modified: gocept.zeoraid/trunk/src/gocept/zeoraid/tests/test_basics.py
===================================================================
--- gocept.zeoraid/trunk/src/gocept/zeoraid/tests/test_basics.py	2009-01-08 10:12:47 UTC (rev 94615)
+++ gocept.zeoraid/trunk/src/gocept/zeoraid/tests/test_basics.py	2009-01-08 11:57:09 UTC (rev 94616)
@@ -42,6 +42,7 @@
 from ZEO.ClientStorage import ClientStorage
 from ZEO.tests import forker, CommitLockTests, ThreadTests
 from ZEO.tests.testZEO import get_port
+import ZEO.runzeo
 
 import ZODB.interfaces
 import ZEO.interfaces
@@ -1239,7 +1240,10 @@
         self._storage.tpc_begin(t)
         self.assertEquals('degraded', self._storage.raid_status())
 
+    def test_reload_without_zeo(self):
+        self.assertRaises(RuntimeError, self._storage.raid_reload)
 
+
 class FailingStorageTests(FailingStorageTestBase,
                           FailingStorageTestSetup):
 
@@ -1455,7 +1459,18 @@
 
 class ExtensionMethodsTests(ZEOStorageBackendTests):
 
-    def saveConfig(self, storages):
+    def open(self):
+        self.zeo_configfile = tempfile.mktemp()
+        self._server_storage_files.append(self.zeo_configfile)
+        self.update_config()
+
+        options = ZEO.runzeo.ZEOOptions()
+        options.realize(['-C', self.zeo_configfile])
+        zeo = ZEO.runzeo.ZEOServer(options)
+        zeo.open_storages()
+        self._storage = zeo.storages['teststorage']
+
+    def update_config(self):
         # create a config file and save it
         file_contents = """\
             %%import gocept.zeoraid
@@ -1463,10 +1478,10 @@
                 address 127.0.0.1:%s
             </zeo>
 
-            <raidstorage main>
+            <raidstorage teststorage>
             """ % get_port()
 
-        for count, storage in enumerate(storages):
+        for count, storage in enumerate(self._storages):
             file_contents += """\
                 <zeoclient %s>
                     server %s:%s
@@ -1479,15 +1494,15 @@
             </raidstorage>
             """
 
-        filename = tempfile.mktemp()
-        self._server_storage_files = [ ]
-        self._server_storage_files.append(filename)
-        f = open(filename, 'w')
+        f = open(self.zeo_configfile, 'w')
         f.write(file_contents)
         f.close()
-        return filename
 
     def test_reload_add(self):
+        self.assertEquals(len(self._storage.openers), 5)
+        self.assertEquals([], self._storage.storages_degraded)
+
+        # set up a new backend
         port = get_port()
         zconf = forker.ZEOConfig(('', port))
         zport, adminaddr, pid, path = forker.start_zeo_server(self.getConfig(),
@@ -1498,40 +1513,45 @@
                                         min_disconnect_poll=0.5, wait=1,
                                         wait_timeout=60))
 
-        filename = self.saveConfig(self._storages)
+        # configure the RAID to use the new backend
+        self.update_config()
+        self._storage.raid_reload()
 
-        self.assertEquals(len(self._storage.openers), 5)
-        self.assertEquals([], self._storage.storages_degraded)
-        self._storage.raid_reload(filename)
         self.assertEquals(len(self._storage.openers), 6)
         self.assertEquals(['5'], self._storage.storages_degraded)
 
+        # ensure that we can still write to the RAID
         oid = self._storage.new_oid()
         self._dostore(oid=oid, data='0', already_pickled=True)
+
+        # recover the newly added backend
         self._storage._recover_impl('5')
         self.assertEquals([], self._storage.storages_degraded)
 
+        # ensure that we can still write to the RAID
         oid2 = self._storage.new_oid()
         self._dostore(oid=oid2, data='1', already_pickled=True)
         self.assertEquals([], self._storage.storages_degraded)
 
+        # ensure that all transactions are available from the new backend
         self.assertEquals('5', self._storages[-1].name)
         s5 = self._storages[-1].open()
         self.assertEquals('0', s5.load(oid)[0])
         self.assertEquals('1', s5.load(oid2)[0])
+
         s5.close()
 
     def test_reload_remove(self):
-        # Remove the 4th storage
-        storages = [s for c,s in enumerate(self._storages) if c != 3]
-        filename = self.saveConfig(storages)
+        self.assertEquals(len(self._storage.storages_degraded), 0)
 
-        # test if the storage was removed (disabled, actually)
-        self.assertEquals(len(self._storage.storages_degraded), 0)
-        self._storage.raid_reload(filename)
+        del self._storages[3]
+
+        # configure the RAID to no longer use the removed backend
+        self.update_config()
+        self._storage.raid_reload()
         self.assertEquals(len(self._storage.storages_degraded), 1)
 
-        # do a simple store to see if anything breaks
+        # ensure that we can still write to the RAID
         self._dostore()
 
 



More information about the Checkins mailing list