changeset 172:27492ea65657

More work on initialization/teardown: - Share the same Mercurial command server across requests. - Better handling of database sessions.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 28 Jan 2014 08:16:35 -0800
parents 8701790360e0
children bf2c79779800
files wikked/db/base.py wikked/db/sql.py wikked/scm/mercurial.py wikked/web.py wikked/wiki.py
diffstat 5 files changed, 37 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/wikked/db/base.py	Tue Jan 28 08:14:35 2014 -0800
+++ b/wikked/db/base.py	Tue Jan 28 08:16:35 2014 -0800
@@ -10,9 +10,6 @@
     def initDb(self, wiki):
         raise NotImplementedError()
 
-    def open(self):
-        raise NotImplementedError()
-
     def close(self):
         raise NotImplementedError()
 
--- a/wikked/db/sql.py	Tue Jan 28 08:14:35 2014 -0800
+++ b/wikked/db/sql.py	Tue Jan 28 08:16:35 2014 -0800
@@ -118,23 +118,15 @@
 
     def __init__(self, config):
         Database.__init__(self)
-        self.engine = None
-        self.session = None
         self.engine_url = config.get('wiki', 'database_url')
         self.auto_update = config.getboolean('wiki', 'auto_update')
+        self._engine = None
+        self._session = None
 
     def initDb(self, wiki):
         self.wiki = wiki
 
-        logger.info("Using database from URL: %s" % self.engine_url)
-        self.engine = create_engine(self.engine_url, convert_unicode=True)
-        self.session = scoped_session(sessionmaker(
-                autocommit=False,
-                autoflush=False,
-                bind=self.engine))
-
-        Base.query = self.session.query_property()
-
+    def createDb(self):
         create_schema = False
         if self.engine_url != 'sqlite:///:memory:':
             # The existing schema is outdated, re-create it.
@@ -152,11 +144,27 @@
         if create_schema:
             self._createSchema()
 
-    def open(self):
-        logger.debug("Opening connection")
+    @property
+    def engine(self):
+        if self._engine is None:
+            self._engine = create_engine(self.engine_url, convert_unicode=True)
+        return self._engine
 
-    def close(self):
-        logger.debug("Closing connection")
+    @property
+    def session(self):
+        if self._session is None:
+            logger.info("Opening database from URL: %s" % self.engine_url)
+            self._session = scoped_session(sessionmaker(
+                    autocommit=False,
+                    autoflush=False,
+                    bind=self.engine))
+        return self._session
+
+    def close(self, commit, exception):
+        if self._session is not None:
+            if commit and exception is None:
+                self._session.commit()
+            self._session.remove()
 
     def reset(self, pages):
         logger.debug("Re-creating SQL database.")
--- a/wikked/scm/mercurial.py	Tue Jan 28 08:14:35 2014 -0800
+++ b/wikked/scm/mercurial.py	Tue Jan 28 08:16:35 2014 -0800
@@ -174,11 +174,13 @@
 
 
 class MercurialCommandServerSourceControl(MercurialBaseSourceControl):
-    def __init__(self, root):
+    def __init__(self, root, client=None):
         MercurialBaseSourceControl.__init__(self, root)
 
-        import hglib
-        self.client = hglib.open(self.root)
+        if client is None:
+            import hglib
+            client = hglib.open(root)
+        self.client = client
 
     def getHistory(self, path=None, limit=10):
         if path is not None:
--- a/wikked/web.py	Tue Jan 28 08:14:35 2014 -0800
+++ b/wikked/web.py	Tue Jan 28 08:16:35 2014 -0800
@@ -77,11 +77,11 @@
 @app.teardown_appcontext
 def shutdown_session(exception=None):
     wiki = getattr(g, 'wiki', None)
-    if wiki and wiki.db.session is not None:
-        if app.config['SQL_COMMIT_ON_TEARDOWN'] and exception is None:
-            wiki.db.session.commit()
-        wiki.db.session.remove()
-        return exception
+    if wiki:
+        wiki.db.close(
+                commit=app.config['SQL_COMMIT_ON_TEARDOWN'],
+                exception=exception)
+    return exception
 
 
 # Login extension.
--- a/wikked/wiki.py	Tue Jan 28 08:14:35 2014 -0800
+++ b/wikked/wiki.py	Tue Jan 28 08:16:35 2014 -0800
@@ -82,9 +82,12 @@
                     scm_type = 'hg'
 
             if scm_type == 'hg':
+                # Only create the command server once.
+                import hglib
+                client = hglib.open(self.root)
                 def impl():
                     from wikked.scm.mercurial import MercurialCommandServerSourceControl
-                    return MercurialCommandServerSourceControl(self.root)
+                    return MercurialCommandServerSourceControl(self.root, client)
                 self._scm_factory = impl
             elif scm_type == 'git':
                 def impl():
@@ -158,8 +161,6 @@
         if parameters is None:
             raise ValueError("No parameters were given to the wiki.")
 
-        logger.debug("Initializing wiki.")
-
         self.formatters = parameters.formatters
         self.special_filenames = parameters.getSpecialFilenames()