changeset 177:9cc75ad9d6d1

infrastructure to shutdown / close resources of the app, storage, etc. storage backends now have a close() method, that shall close/free all resources used. currently, this is mostly used to dispose sqlalchemy engines.
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 10 Apr 2011 22:55:56 +0200
parents 429ca1c60a1f
children 2f1708707657 e771511ea996
files MoinMoin/app.py MoinMoin/conftest.py MoinMoin/storage/__init__.py MoinMoin/storage/backends/fs19.py MoinMoin/storage/backends/fs2.py MoinMoin/storage/backends/indexing.py MoinMoin/storage/backends/router.py MoinMoin/storage/backends/sqla.py
diffstat 8 files changed, 52 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/app.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/app.py	Sun Apr 10 22:55:56 2011 +0200
@@ -152,6 +152,9 @@
     del clock
     return app
 
+def destroy_app(app):
+    deinit_backends(app)
+
 
 from MoinMoin.util.clock import Clock
 from MoinMoin.storage.error import StorageError
@@ -187,6 +190,10 @@
     storage = router.RouterBackend(protected_mapping, index_uri=index_uri)
     return unprotected_storage, storage
 
+def deinit_backends(app):
+    app.storage.close()
+    app.unprotected_storage.close()
+
 
 def import_export_xml(app):
     # If the content was already pumped into the backend, we don't want
--- a/MoinMoin/conftest.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/conftest.py	Sun Apr 10 22:55:56 2011 +0200
@@ -30,7 +30,7 @@
 
 import py
 
-from MoinMoin.app import create_app_ext, before_wiki, after_wiki
+from MoinMoin.app import create_app_ext, destroy_app, before_wiki, after_wiki
 from MoinMoin._tests import maketestwiki, wikiconfig
 from MoinMoin.storage.backends import create_simple_mapping
 
@@ -78,9 +78,10 @@
     before_wiki()
     return app, ctx
 
-def deinit_test_app(ctx):
+def deinit_test_app(app, ctx):
     after_wiki('')
     ctx.pop()
+    destroy_app(app)
 
 
 class MoinClassCollector(py.test.collect.Class):
@@ -106,7 +107,7 @@
                 # Important: FIRST call the wrapped function, so it can still
                 # access the stuff removed by deinit_test_app:
                 ret = f(self, *args, **kwargs)
-                deinit_test_app(self.ctx)
+                deinit_test_app(self.app, self.ctx)
                 return ret
             return wrapper
 
@@ -125,7 +126,7 @@
         except AttributeError:
             # Perhaps the test class did not define a teardown_method.
             def no_teardown(self, method):
-                deinit_test_app(self.ctx)
+                deinit_test_app(self.app, self.ctx)
             cls.teardown_method = no_teardown
 
         super(MoinClassCollector, self).setup()
--- a/MoinMoin/storage/__init__.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/storage/__init__.py	Sun Apr 10 22:55:56 2011 +0200
@@ -75,6 +75,18 @@
     # _create_revision() method of the item's backend is
     # invoked and the item passes itself as parameter.
     #
+    def __init__(self, *args, **kw):
+        """
+        Create the backend instance.
+        """
+        pass
+
+    def close(self):
+        """
+        Close all resources the backend is using.
+        """
+        pass
+
     def search_items(self, searchterm):
         """
         Takes a MoinMoin search term and returns an iterator (maybe empty) over
--- a/MoinMoin/storage/backends/fs19.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/storage/backends/fs19.py	Sun Apr 10 22:55:56 2011 +0200
@@ -80,6 +80,10 @@
                        )
         metadata.create_all()
 
+    def close(self):
+        engine = self.users.metadata.bind
+        engine.dispose()
+
     def user_uuid(self, name='', old_id='', refcount=False):
         """
         Get uuid for user name, create a new uuid if we don't already have one.
@@ -187,6 +191,9 @@
         self.item_category_regex = re.compile(item_category_regex, re.UNICODE)
         self.idx = Index(idx_path)
 
+    def close(self):
+        self.idx.close()
+
     def _get_item_path(self, name, *args):
         """
         Returns the full path to the page directory.
--- a/MoinMoin/storage/backends/fs2.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/storage/backends/fs2.py	Sun Apr 10 22:55:56 2011 +0200
@@ -134,6 +134,10 @@
 
         metadata.create_all()
 
+    def close(self):
+        engine = self._name2id.metadata.bind
+        engine.dispose()
+
     def _make_path(self, *args):
         return os.path.join(self._path, *args)
 
--- a/MoinMoin/storage/backends/indexing.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/storage/backends/indexing.py	Sun Apr 10 22:55:56 2011 +0200
@@ -42,6 +42,10 @@
         super(IndexingBackendMixin, self).__init__(*args, **kw)
         self._index = ItemIndex(index_uri)
 
+    def close(self):
+        self._index.close()
+        super(IndexingBackendMixin, self).close()
+
     def create_item(self, itemname):
         """
         intercept new item creation and make sure there is NAME / UUID in the item
@@ -246,6 +250,10 @@
         self.item_kvstore = KVStore(item_kvmeta)
         self.rev_kvstore = KVStore(rev_kvmeta)
 
+    def close(self):
+        engine = self.metadata.bind
+        engine.dispose()
+
     def index_rebuild(self, backend):
         self.metadata.drop_all()
         self.metadata.create_all()
--- a/MoinMoin/storage/backends/router.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/storage/backends/router.py	Sun Apr 10 22:55:56 2011 +0200
@@ -59,6 +59,12 @@
         super(BareRouterBackend, self).__init__(*args, **kw)
         self.mapping = [(mountpoint.rstrip('/'), backend) for mountpoint, backend in mapping]
 
+    def close(self):
+        super(BareRouterBackend, self).close()
+        for mountpoint, backend in self.mapping:
+            backend.close()
+        self.mapping = []
+
     def _get_backend(self, itemname):
         """
         For a given fully-qualified itemname (i.e. something like Company/Bosses/Mr_Joe)
--- a/MoinMoin/storage/backends/sqla.py	Sun Apr 10 19:42:34 2011 +0200
+++ b/MoinMoin/storage/backends/sqla.py	Sun Apr 10 22:55:56 2011 +0200
@@ -122,6 +122,9 @@
         # {id : Lockobject} -- lock registry for item metadata locks
         self._item_metadata_lock = {}
 
+    def close(self):
+        self.engine.dispose()
+
     def has_item(self, itemname):
         """
         @see: Backend.has_item.__doc__