diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-10-24 10:11:12 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-10-24 13:45:50 -0400 |
commit | 5b36e169ea74d2345545169124c31cdb6c319408 (patch) | |
tree | 776025d85f3b33fafbb36cb9f47bd7ea44335a1a | |
parent | baa0a045b51fd261fdcef6f7dfafe8e823f26e7a (diff) | |
download | oslo-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.py | 21 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_enginefacade.py | 26 | ||||
-rw-r--r-- | releasenotes/notes/add_facade_started-14f9bc34fac89371.yaml | 8 |
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``. |