Switch disk_config extension to use one DB query

A response through this extension can have many servers and making one
query per server can slow down response time dramatically. This change
switches the extension to use one DB query instead of many queries.
It also avoids queries when the key is already populated, such as when
the results include responses from a remote zone.

This change reduces a 'nova list' of 21 servers from 14 seconds to 1
second on my (relatively slow) development system.

Change-Id: I8476dbca0f87ff2a3d69bd7b8f51c296e41e3388
This commit is contained in:
Johannes Erdfelt
2011-12-15 15:21:11 +00:00
parent c421328c56
commit a72a66c206
2 changed files with 25 additions and 10 deletions

View File

@@ -23,6 +23,7 @@ from webob import exc
from nova.api.openstack.v2 import extensions
from nova.api.openstack import xmlutil
from nova import compute
from nova import db
from nova import log as logging
from nova import utils
@@ -118,10 +119,20 @@ class Disk_config(extensions.ExtensionDescriptor):
singular='server', singular_template=ServerDiskConfigTemplate(),
plural='servers', plural_template=ServersDiskConfigTemplate())
# Filter out any servers that already have the key set (most likely
# from a remote zone)
servers = filter(lambda s: self.API_DISK_CONFIG not in s, servers)
# Get DB information for servers
uuids = [server['id'] for server in servers]
db_servers = db.instance_get_all_by_filters(context, {'uuid': uuids})
db_servers = dict([(s['uuid'], s) for s in db_servers])
for server in servers:
db_server = self.compute_api.routing_get(context, server['id'])
value = db_server[self.INTERNAL_DISK_CONFIG]
server[self.API_DISK_CONFIG] = disk_config_to_api(value)
db_server = db_servers.get(server['id'])
if db_server:
value = db_server[self.INTERNAL_DISK_CONFIG]
server[self.API_DISK_CONFIG] = disk_config_to_api(value)
return res

View File

@@ -60,7 +60,6 @@ class DiskConfigTestCase(test.TestCase):
if id_ == instance['id']:
return instance
self.stubs.Set(nova.db.api, 'instance_get', fake_instance_get)
self.stubs.Set(nova.db, 'instance_get', fake_instance_get)
def fake_instance_get_by_uuid(context, uuid):
@@ -75,7 +74,7 @@ class DiskConfigTestCase(test.TestCase):
return FAKE_INSTANCES
self.stubs.Set(nova.db, 'instance_get_all', fake_instance_get_all)
self.stubs.Set(nova.db.api, 'instance_get_all_by_filters',
self.stubs.Set(nova.db, 'instance_get_all_by_filters',
fake_instance_get_all)
def fake_instance_create(context, inst_, session=None):
@@ -91,21 +90,26 @@ class DiskConfigTestCase(test.TestCase):
inst['progress'] = 0
inst['name'] = 'instance-1' # this is a property
def fake_instance_get_for_create(context, id_, session=None):
def fake_instance_get_for_create(context, id_, *args, **kwargs):
return inst
self.stubs.Set(nova.db, 'instance_get',
fake_instance_get_for_create)
self.stubs.Set(nova.db.api, 'instance_get',
fake_instance_get_for_create)
self.stubs.Set(nova.db.sqlalchemy.api, 'instance_get',
self.stubs.Set(nova.db, 'instance_update',
fake_instance_get_for_create)
def fake_instance_get_all_for_create(context, *args, **kwargs):
return [inst]
self.stubs.Set(nova.db, 'instance_get_all',
fake_instance_get_all_for_create)
self.stubs.Set(nova.db, 'instance_get_all_by_filters',
fake_instance_get_all_for_create)
def fake_instance_add_security_group(context, instance_id,
security_group_id):
pass
self.stubs.Set(nova.db.sqlalchemy.api,
self.stubs.Set(nova.db,
'instance_add_security_group',
fake_instance_add_security_group)