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
This commit is contained in:
parent
baa0a045b5
commit
5b36e169ea
@ -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.
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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``.
|
Loading…
Reference in New Issue
Block a user