Browse Source

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
Mike Bayer 5 months ago
parent
commit
5b36e169ea

+ 20
- 1
oslo_db/sqlalchemy/enginefacade.py View File

@@ -120,6 +120,14 @@ class _Default(object):
120 120
             hasattr(conf_namespace, key)
121 121
 
122 122
 
123
+class AlreadyStartedError(TypeError):
124
+    """Raises when a factory is being asked to initialize a second time.
125
+
126
+    Subclasses :class:`.TypeError` for legacy support.
127
+
128
+    """
129
+
130
+
123 131
 class _TransactionFactory(object):
124 132
     """A factory for :class:`._TransactionContext` objects.
125 133
 
@@ -314,7 +322,8 @@ class _TransactionFactory(object):
314 322
     def _configure(self, as_defaults, kw):
315 323
 
316 324
         if self._started:
317
-            raise TypeError("this TransactionFactory is already started")
325
+            raise AlreadyStartedError(
326
+                "this TransactionFactory is already started")
318 327
         not_supported = []
319 328
         for k, v in kw.items():
320 329
             for dict_ in (
@@ -464,6 +473,11 @@ class _TransactionFactory(object):
464 473
             if self._reader_engine is not self._writer_engine:
465 474
                 self._reader_engine.pool.dispose()
466 475
 
476
+    @property
477
+    def is_started(self):
478
+        """True if this :class:`._TransactionFactory` is already started."""
479
+        return self._started
480
+
467 481
     def _start(self, conf=False, connection=None, slave_connection=None):
468 482
         with self._start_lock:
469 483
             # self._started has been checked on the outside
@@ -777,6 +791,11 @@ class _TransactionContextManager(object):
777 791
         """The :class:`._TransactionFactory` associated with this context."""
778 792
         return self._root._root_factory
779 793
 
794
+    @property
795
+    def is_started(self):
796
+        """True if this manager is already started."""
797
+        return self._factory.is_started
798
+
780 799
     def configure(self, **kw):
781 800
         """Apply configurational options to the factory.
782 801
 

+ 26
- 0
oslo_db/tests/sqlalchemy/test_enginefacade.py View File

@@ -479,6 +479,32 @@ class MockFacadeTest(oslo_test_base.BaseTestCase):
479 479
             [mock.call.dispose()]
480 480
         )
481 481
 
482
+    def test_started_flag(self):
483
+        facade = enginefacade.transaction_context()
484
+
485
+        self.assertFalse(facade.is_started)
486
+        facade.configure(connection=self.engine_uri)
487
+        facade.writer.get_engine()
488
+
489
+        self.assertTrue(facade.is_started)
490
+
491
+    def test_started_exception(self):
492
+        facade = enginefacade.transaction_context()
493
+
494
+        self.assertFalse(facade.is_started)
495
+        facade.configure(connection=self.engine_uri)
496
+        facade.writer.get_engine()
497
+
498
+        exc = self.assertRaises(
499
+            enginefacade.AlreadyStartedError,
500
+            facade.configure,
501
+            connection=self.engine_uri
502
+        )
503
+        self.assertEqual(
504
+            "this TransactionFactory is already started",
505
+            exc.args[0]
506
+        )
507
+
482 508
     def test_session_reader_decorator(self):
483 509
         context = oslo_context.RequestContext()
484 510
 

+ 8
- 0
releasenotes/notes/add_facade_started-14f9bc34fac89371.yaml View File

@@ -0,0 +1,8 @@
1
+---
2
+features:
3
+  - |
4
+    Added new ``.is_started`` boolean flag to enginefacade context manager
5
+    and factory objects, so that double-configure scenarios can be prevented
6
+    by calling code.   Additionally, the ``TypeError`` raised when configure
7
+    is called after the factory is started is now a specific subclass
8
+    ``enginefacade.AlreadyStartedError``.

Loading…
Cancel
Save