Merge "Move Enforcer caching closer to limit retrieval"
This commit is contained in:
commit
6451b4f61e
|
@ -343,28 +343,15 @@ class _EnforcerUtils(object):
|
||||||
# to the cache. Do this for both project limits and registered limits.
|
# to the cache. Do this for both project limits and registered limits.
|
||||||
|
|
||||||
# Look for a project limit first.
|
# Look for a project limit first.
|
||||||
if (project_id in self.plimit_cache and
|
|
||||||
resource_name in self.plimit_cache[project_id]):
|
|
||||||
return self.plimit_cache[project_id][resource_name].resource_limit
|
|
||||||
|
|
||||||
project_limit = (self._get_project_limit(project_id, resource_name)
|
project_limit = (self._get_project_limit(project_id, resource_name)
|
||||||
if project_id is not None else None)
|
if project_id is not None else None)
|
||||||
|
|
||||||
if self.should_cache and project_limit:
|
|
||||||
self.plimit_cache[project_id][resource_name] = project_limit
|
|
||||||
|
|
||||||
if project_limit:
|
if project_limit:
|
||||||
return project_limit.resource_limit
|
return project_limit.resource_limit
|
||||||
|
|
||||||
# If there is no project limit, look for a registered limit.
|
# If there is no project limit, look for a registered limit.
|
||||||
if resource_name in self.rlimit_cache:
|
|
||||||
return self.rlimit_cache[resource_name].default_limit
|
|
||||||
|
|
||||||
registered_limit = self._get_registered_limit(resource_name)
|
registered_limit = self._get_registered_limit(resource_name)
|
||||||
|
|
||||||
if self.should_cache and registered_limit:
|
|
||||||
self.rlimit_cache[resource_name] = registered_limit
|
|
||||||
|
|
||||||
if registered_limit:
|
if registered_limit:
|
||||||
return registered_limit.default_limit
|
return registered_limit.default_limit
|
||||||
|
|
||||||
|
@ -376,22 +363,45 @@ class _EnforcerUtils(object):
|
||||||
raise _LimitNotFound(resource_name)
|
raise _LimitNotFound(resource_name)
|
||||||
|
|
||||||
def _get_project_limit(self, project_id, resource_name):
|
def _get_project_limit(self, project_id, resource_name):
|
||||||
limit = self.connection.limits(
|
# Look in the cache first.
|
||||||
|
if (project_id in self.plimit_cache and
|
||||||
|
resource_name in self.plimit_cache[project_id]):
|
||||||
|
return self.plimit_cache[project_id][resource_name]
|
||||||
|
|
||||||
|
# Get the limit from keystone.
|
||||||
|
limits = self.connection.limits(
|
||||||
service_id=self._service_id,
|
service_id=self._service_id,
|
||||||
region_id=self._region_id,
|
region_id=self._region_id,
|
||||||
resource_name=resource_name,
|
resource_name=resource_name,
|
||||||
project_id=project_id)
|
project_id=project_id)
|
||||||
try:
|
try:
|
||||||
return next(limit)
|
limit = next(limits)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# Cache the limit if configured.
|
||||||
|
if self.should_cache and limit:
|
||||||
|
self.plimit_cache[project_id][resource_name] = limit
|
||||||
|
|
||||||
|
return limit
|
||||||
|
|
||||||
def _get_registered_limit(self, resource_name):
|
def _get_registered_limit(self, resource_name):
|
||||||
reg_limit = self.connection.registered_limits(
|
# Look in the cache first.
|
||||||
|
if resource_name in self.rlimit_cache:
|
||||||
|
return self.rlimit_cache[resource_name]
|
||||||
|
|
||||||
|
# Get the limit from keystone.
|
||||||
|
reg_limits = self.connection.registered_limits(
|
||||||
service_id=self._service_id,
|
service_id=self._service_id,
|
||||||
region_id=self._region_id,
|
region_id=self._region_id,
|
||||||
resource_name=resource_name)
|
resource_name=resource_name)
|
||||||
try:
|
try:
|
||||||
return next(reg_limit)
|
reg_limit = next(reg_limits)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# Cache the limit if configured.
|
||||||
|
if self.should_cache and reg_limit:
|
||||||
|
self.rlimit_cache[resource_name] = reg_limit
|
||||||
|
|
||||||
|
return reg_limit
|
||||||
|
|
|
@ -399,6 +399,48 @@ class TestEnforcerUtils(base.BaseTestCase):
|
||||||
limits = utils.get_project_limits(project_id, ["c", "d"])
|
limits = utils.get_project_limits(project_id, ["c", "d"])
|
||||||
self.assertEqual([('c', 0), ('d', 0)], limits)
|
self.assertEqual([('c', 0), ('d', 0)], limits)
|
||||||
|
|
||||||
|
def test__get_project_limit_cache(self, cache=True):
|
||||||
|
# Registered limit = 5 and project limit = 3
|
||||||
|
project_id = uuid.uuid4().hex
|
||||||
|
fix = self.useFixture(
|
||||||
|
fixture.LimitFixture({'foo': 5}, {project_id: {'foo': 3}}))
|
||||||
|
|
||||||
|
utils = limit._EnforcerUtils(cache=cache)
|
||||||
|
foo_limit = utils._get_project_limit(project_id, 'foo')
|
||||||
|
|
||||||
|
self.assertEqual(3, foo_limit.resource_limit)
|
||||||
|
self.assertEqual(1, fix.mock_conn.limits.call_count)
|
||||||
|
|
||||||
|
# Second call should be cached, so call_count for project limits should
|
||||||
|
# remain 1. When cache is disabled, it should increase to 2
|
||||||
|
foo_limit = utils._get_project_limit(project_id, 'foo')
|
||||||
|
count = 1 if cache else 2
|
||||||
|
self.assertEqual(count, fix.mock_conn.limits.call_count)
|
||||||
|
|
||||||
|
def test__get_project_limit_cache_no_cache(self):
|
||||||
|
self.test__get_project_limit_cache(cache=False)
|
||||||
|
|
||||||
|
def test__get_registered_limit_cache(self, cache=True):
|
||||||
|
# Registered limit = 5 and project limit = 3
|
||||||
|
project_id = uuid.uuid4().hex
|
||||||
|
fix = self.useFixture(
|
||||||
|
fixture.LimitFixture({'foo': 5}, {project_id: {'foo': 3}}))
|
||||||
|
|
||||||
|
utils = limit._EnforcerUtils(cache=cache)
|
||||||
|
foo_limit = utils._get_registered_limit('foo')
|
||||||
|
|
||||||
|
self.assertEqual(5, foo_limit.default_limit)
|
||||||
|
self.assertEqual(1, fix.mock_conn.registered_limits.call_count)
|
||||||
|
|
||||||
|
# Second call should be cached, so call_count for project limits should
|
||||||
|
# remain 1. When cache is disabled, it should increase to 2
|
||||||
|
foo_limit = utils._get_registered_limit('foo')
|
||||||
|
count = 1 if cache else 2
|
||||||
|
self.assertEqual(count, fix.mock_conn.registered_limits.call_count)
|
||||||
|
|
||||||
|
def test__get_registered_limit_cache_no_cache(self):
|
||||||
|
self.test__get_registered_limit_cache(cache=False)
|
||||||
|
|
||||||
def test_get_limit_cache(self, cache=True):
|
def test_get_limit_cache(self, cache=True):
|
||||||
# No project limit and registered limit = 5
|
# No project limit and registered limit = 5
|
||||||
fix = self.useFixture(fixture.LimitFixture({'foo': 5}, {}))
|
fix = self.useFixture(fixture.LimitFixture({'foo': 5}, {}))
|
||||||
|
|
Loading…
Reference in New Issue