Skip to content

Commit

Permalink
Add caching for ec2 mapping ids.
Browse files Browse the repository at this point in the history
Requests to map ec2 ids can be slow when there are a large number
of instances. These shouldn't ever change so cache them in memory
for a week. The one week timeout is simply to prevent memory from
growing uncontrollably.

Fixes bug 1157437

Change-Id: I3f1c68959a933a7aaa50f122c34a716264c8722d
(cherry picked from commit 7684443)
  • Loading branch information
vishvananda authored and Chuck Short committed Mar 26, 2013
1 parent 49c4334 commit e547005
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
33 changes: 33 additions & 0 deletions nova/api/ec2/ec2utils.py
Expand Up @@ -16,6 +16,7 @@
# License for the specific language governing permissions and limitations
# under the License.

import functools
import re

from nova import availability_zones
Expand All @@ -24,10 +25,34 @@
from nova import exception
from nova.network import model as network_model
from nova.openstack.common import log as logging
from nova.openstack.common import memorycache
from nova.openstack.common import timeutils
from nova.openstack.common import uuidutils

LOG = logging.getLogger(__name__)
# NOTE(vish): cache mapping for one week
_CACHE_TIME = 7 * 24 * 60 * 60
_CACHE = None


def memoize(func):
@functools.wraps(func)
def memoizer(context, reqid):
global _CACHE
if not _CACHE:
_CACHE = memorycache.get_client()
key = "%s:%s" % (func.__name__, reqid)
value = _CACHE.get(key)
if value is None:
value = func(context, reqid)
_CACHE.set(key, value, time=_CACHE_TIME)
return value
return memoizer


def reset_cache():
global _CACHE
_CACHE = None


def image_type(image_type):
Expand All @@ -47,11 +72,13 @@ def image_type(image_type):
return image_type


@memoize
def id_to_glance_id(context, image_id):
"""Convert an internal (db) id to a glance id."""
return db.s3_image_get(context, image_id)['uuid']


@memoize
def glance_id_to_id(context, glance_id):
"""Convert a glance id to an internal (db) id."""
if glance_id is None:
Expand Down Expand Up @@ -145,6 +172,7 @@ def ec2_inst_id_to_uuid(context, ec2_id):
return get_instance_uuid_from_int_id(context, int_id)


@memoize
def get_instance_uuid_from_int_id(context, int_id):
return db.get_instance_uuid_by_ec2_id(context, int_id)

Expand Down Expand Up @@ -211,6 +239,7 @@ def is_ec2_timestamp_expired(request, expires=None):
return True


@memoize
def get_int_id_from_instance_uuid(context, instance_uuid):
if instance_uuid is None:
return
Expand All @@ -220,6 +249,7 @@ def get_int_id_from_instance_uuid(context, instance_uuid):
return db.ec2_instance_create(context, instance_uuid)['id']


@memoize
def get_int_id_from_volume_uuid(context, volume_uuid):
if volume_uuid is None:
return
Expand All @@ -229,6 +259,7 @@ def get_int_id_from_volume_uuid(context, volume_uuid):
return db.ec2_volume_create(context, volume_uuid)['id']


@memoize
def get_volume_uuid_from_int_id(context, int_id):
return db.get_volume_uuid_by_ec2_id(context, int_id)

Expand All @@ -242,6 +273,7 @@ def ec2_snap_id_to_uuid(ec2_id):
return get_snapshot_uuid_from_int_id(ctxt, int_id)


@memoize
def get_int_id_from_snapshot_uuid(context, snapshot_uuid):
if snapshot_uuid is None:
return
Expand All @@ -251,6 +283,7 @@ def get_int_id_from_snapshot_uuid(context, snapshot_uuid):
return db.ec2_snapshot_create(context, snapshot_uuid)['id']


@memoize
def get_snapshot_uuid_from_int_id(context, int_id):
return db.get_snapshot_uuid_by_ec2_id(context, int_id)

Expand Down
1 change: 1 addition & 0 deletions nova/tests/api/ec2/test_cinder_cloud.py
Expand Up @@ -88,6 +88,7 @@ def get_instances_with_cached_ips(orig_func, *args, **kwargs):
class CinderCloudTestCase(test.TestCase):
def setUp(self):
super(CinderCloudTestCase, self).setUp()
ec2utils.reset_cache()
vol_tmpdir = self.useFixture(fixtures.TempDir()).path
self.flags(compute_driver='nova.virt.fake.FakeDriver',
volume_api_class='nova.tests.fake_volume.API')
Expand Down
1 change: 1 addition & 0 deletions nova/tests/api/ec2/test_cloud.py
Expand Up @@ -106,6 +106,7 @@ def get_instances_with_cached_ips(orig_func, *args, **kwargs):
class CloudTestCase(test.TestCase):
def setUp(self):
super(CloudTestCase, self).setUp()
ec2utils.reset_cache()
self.flags(compute_driver='nova.virt.fake.FakeDriver',
volume_api_class='nova.tests.fake_volume.API')
self.useFixture(fixtures.FakeLogger('boto'))
Expand Down

0 comments on commit e547005

Please sign in to comment.