summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-10-24 10:11:12 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-10-24 13:45:50 -0400
commit5b36e169ea74d2345545169124c31cdb6c319408 (patch)
tree776025d85f3b33fafbb36cb9f47bd7ea44335a1a
parentbaa0a045b51fd261fdcef6f7dfafe8e823f26e7a (diff)
downloadoslo-db-5b36e169ea74d2345545169124c31cdb6c319408.tar.gz
Add "is_started" flag to enginefacade
Some module reloading scenarios such as that which occurs within mod_wsgi mean that an existing module-level enginefacade is already in the "started" state, however initialization routines from the calling application may still attempt to call the ``.configure`` method. Add a new flag is_started to both _TransactionContextManager and _TransactionFactory so that calling code can check for this state ahead of time; additionally, promote the TypeError raised to a specific subclass enginefacade.AlreadyStartedError to allow for better optimistic schemes. Change-Id: I2f5a9e35c2fae0c28b78beef3dcd2c4794362766 References: I704196711d30c1124e713ac31111a8ea6fa2f1ba
-rw-r--r--oslo_db/sqlalchemy/enginefacade.py21
-rw-r--r--oslo_db/tests/sqlalchemy/test_enginefacade.py26
-rw-r--r--releasenotes/notes/add_facade_started-14f9bc34fac89371.yaml8
3 files changed, 54 insertions, 1 deletions
diff --git a/oslo_db/sqlalchemy/enginefacade.py b/oslo_db/sqlalchemy/enginefacade.py
index 481e166..3618b75 100644
--- a/oslo_db/sqlalchemy/enginefacade.py
+++ b/oslo_db/sqlalchemy/enginefacade.py
@@ -120,6 +120,14 @@ class _Default(object):
hasattr(conf_namespace, key)
+class AlreadyStartedError(TypeError):
+ """Raises when a factory is being asked to initialize a second time.
+
+ Subclasses :class:`.TypeError` for legacy support.
+
+ """
+
+
class _TransactionFactory(object):
"""A factory for :class:`._TransactionContext` objects.
@@ -314,7 +322,8 @@ class _TransactionFactory(object):
def _configure(self, as_defaults, kw):
if self._started:
- raise TypeError("this TransactionFactory is already started")
+ raise AlreadyStartedError(
+ "this TransactionFactory is already started")
not_supported = []
for k, v in kw.items():
for dict_ in (
@@ -464,6 +473,11 @@ class _TransactionFactory(object):
if self._reader_engine is not self._writer_engine:
self._reader_engine.pool.dispose()
+ @property
+ def is_started(self):
+ """True if this :class:`._TransactionFactory` is already started."""
+ return self._started
+
def _start(self, conf=False, connection=None, slave_connection=None):
with self._start_lock:
# self._started has been checked on the outside
@@ -777,6 +791,11 @@ class _TransactionContextManager(object):
"""The :class:`._TransactionFactory` associated with this context."""
return self._root._root_factory
+ @property
+ def is_started(self):
+ """True if this manager is already started."""
+ return self._factory.is_started
+
def configure(self, **kw):
"""Apply configurational options to the factory.
diff --git a/oslo_db/tests/sqlalchemy/test_enginefacade.py b/oslo_db/tests/sqlalchemy/test_enginefacade.py
index cab7547..b29a122 100644
--- a/oslo_db/tests/sqlalchemy/test_enginefacade.py
+++ b/oslo_db/tests/sqlalchemy/test_enginefacade.py
@@ -479,6 +479,32 @@ class MockFacadeTest(oslo_test_base.BaseTestCase):
[mock.call.dispose()]
)
+ def test_started_flag(self):
+ facade = enginefacade.transaction_context()
+
+ self.assertFalse(facade.is_started)
+ facade.configure(connection=self.engine_uri)
+ facade.writer.get_engine()
+
+ self.assertTrue(facade.is_started)
+
+ def test_started_exception(self):
+ facade = enginefacade.transaction_context()
+
+ self.assertFalse(facade.is_started)
+ facade.configure(connection=self.engine_uri)
+ facade.writer.get_engine()
+
+ exc = self.assertRaises(
+ enginefacade.AlreadyStartedError,
+ facade.configure,
+ connection=self.engine_uri
+ )
+ self.assertEqual(
+ "this TransactionFactory is already started",
+ exc.args[0]
+ )
+
def test_session_reader_decorator(self):
context = oslo_context.RequestContext()
diff --git a/releasenotes/notes/add_facade_started-14f9bc34fac89371.yaml b/releasenotes/notes/add_facade_started-14f9bc34fac89371.yaml
new file mode 100644
index 0000000..52154f2
--- /dev/null
+++ b/releasenotes/notes/add_facade_started-14f9bc34fac89371.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - |
+ Added new ``.is_started`` boolean flag to enginefacade context manager
+ and factory objects, so that double-configure scenarios can be prevented
+ by calling code. Additionally, the ``TypeError`` raised when configure
+ is called after the factory is started is now a specific subclass
+ ``enginefacade.AlreadyStartedError``.