Merge "Cache database and message queue connection objects" into stable/newton
This commit is contained in:
commit
a8cd60f7a0
|
@ -34,6 +34,10 @@ from nova import policy
|
|||
from nova import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
# TODO(melwitt): This cache should be cleared whenever WSGIService receives a
|
||||
# SIGHUP and periodically based on an expiration time. Currently, none of the
|
||||
# cell caches are purged, so neither is this one, for now.
|
||||
CELL_CACHE = {}
|
||||
|
||||
|
||||
class _ContextAuthPlugin(plugin.BaseAuthPlugin):
|
||||
|
@ -349,11 +353,27 @@ def target_cell(context, cell_mapping):
|
|||
:param context: The RequestContext to add connection information
|
||||
:param cell_mapping: A objects.CellMapping object
|
||||
"""
|
||||
global CELL_CACHE
|
||||
|
||||
original_db_connection = context.db_connection
|
||||
# avoid circular import
|
||||
from nova import db
|
||||
db_connection_string = cell_mapping.database_connection
|
||||
context.db_connection = db.create_context_manager(db_connection_string)
|
||||
|
||||
# Synchronize access to the cache by multiple API workers.
|
||||
@utils.synchronized(cell_mapping.uuid)
|
||||
def get_or_set_cached_cell_and_set_connections():
|
||||
try:
|
||||
cell_db_conn = CELL_CACHE[cell_mapping.uuid]
|
||||
except KeyError:
|
||||
db_connection_string = cell_mapping.database_connection
|
||||
context.db_connection = db.create_context_manager(
|
||||
db_connection_string)
|
||||
CELL_CACHE[cell_mapping.uuid] = context.db_connection
|
||||
else:
|
||||
context.db_connection = cell_db_conn
|
||||
|
||||
get_or_set_cached_cell_and_set_connections()
|
||||
|
||||
try:
|
||||
yield context
|
||||
finally:
|
||||
|
|
|
@ -211,6 +211,9 @@ class TestCase(testtools.TestCase):
|
|||
self.useFixture(conf_fixture.ConfFixture(CONF))
|
||||
self.useFixture(nova_fixtures.RPCFixture('nova.test'))
|
||||
|
||||
# NOTE(melwitt): Reset the cached db connection objects
|
||||
context.CELL_CACHE = {}
|
||||
|
||||
if self.USES_DB:
|
||||
self.useFixture(nova_fixtures.Database())
|
||||
self.useFixture(nova_fixtures.Database(database='api'))
|
||||
|
|
|
@ -20,6 +20,7 @@ from nova import context
|
|||
from nova import exception
|
||||
from nova import objects
|
||||
from nova import test
|
||||
from nova.tests import uuidsentinel as uuids
|
||||
|
||||
|
||||
class ContextTestCase(test.NoDBTestCase):
|
||||
|
@ -286,7 +287,26 @@ class ContextTestCase(test.NoDBTestCase):
|
|||
roles=['admin', 'weasel'])
|
||||
# Verify the existing db_connection, if any, is restored
|
||||
ctxt.db_connection = mock.sentinel.db_conn
|
||||
mapping = objects.CellMapping(database_connection='fake://')
|
||||
mapping = objects.CellMapping(database_connection='fake://',
|
||||
transport_url='fake://',
|
||||
uuid=uuids.cell)
|
||||
with context.target_cell(ctxt, mapping):
|
||||
self.assertEqual(ctxt.db_connection, mock.sentinel.cm)
|
||||
self.assertEqual(mock.sentinel.db_conn, ctxt.db_connection)
|
||||
|
||||
@mock.patch('nova.db.create_context_manager')
|
||||
def test_target_cell_caching(self, mock_create_cm):
|
||||
mock_create_cm.return_value = mock.sentinel.db_conn_obj
|
||||
ctxt = context.RequestContext('111', '222')
|
||||
mapping = objects.CellMapping(database_connection='fake://db',
|
||||
transport_url='fake://mq',
|
||||
uuid=uuids.cell)
|
||||
# First call should create new connection objects.
|
||||
with context.target_cell(ctxt, mapping):
|
||||
self.assertEqual(mock.sentinel.db_conn_obj, ctxt.db_connection)
|
||||
mock_create_cm.assert_called_once_with('fake://db')
|
||||
# Second call should use cached objects.
|
||||
mock_create_cm.reset_mock()
|
||||
with context.target_cell(ctxt, mapping):
|
||||
self.assertEqual(mock.sentinel.db_conn_obj, ctxt.db_connection)
|
||||
mock_create_cm.assert_not_called()
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes `bug 1691545`_ in which there was a significant increase in database
|
||||
connections because of the way connections to cell databases were being
|
||||
established. With this fix, objects related to database connections are
|
||||
cached in the API service and reused to prevent new connections being
|
||||
established for every communication with cell databases.
|
||||
|
||||
.. _bug 1691545: https://bugs.launchpad.net/nova/+bug/1691545
|
Loading…
Reference in New Issue