diff options
| author | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2011-12-15 15:21:11 +0000 |
|---|---|---|
| committer | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2011-12-15 15:21:11 +0000 |
| commit | a72a66c206cd80aa4b392eb42c29e4a1cd4463f9 (patch) | |
| tree | 31d7523ba163e9fb6a63e536459379e867ac3158 | |
| parent | c421328c5697698adfaacdf053efe715646d069a (diff) | |
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
| -rw-r--r-- | nova/api/openstack/v2/contrib/disk_config.py | 17 | ||||
| -rw-r--r-- | nova/tests/api/openstack/v2/contrib/test_disk_config.py | 18 |
2 files changed, 25 insertions, 10 deletions
diff --git a/nova/api/openstack/v2/contrib/disk_config.py b/nova/api/openstack/v2/contrib/disk_config.py index 6e26c1daa..7ce24a3fd 100644 --- a/nova/api/openstack/v2/contrib/disk_config.py +++ b/nova/api/openstack/v2/contrib/disk_config.py @@ -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 diff --git a/nova/tests/api/openstack/v2/contrib/test_disk_config.py b/nova/tests/api/openstack/v2/contrib/test_disk_config.py index ac2391a04..95cfd3747 100644 --- a/nova/tests/api/openstack/v2/contrib/test_disk_config.py +++ b/nova/tests/api/openstack/v2/contrib/test_disk_config.py @@ -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) |
