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:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user