Optimize CountPoolChildrenForQuota task in amphorav2
The CountPoolChildrenForQuota task takes 3 or 4 seconds to execute in
amphorav2. When cascade deleting a load balancer with many pools (60),
it might take minutes.
We don't need to get and to convert all the fields from the object to
compute the number of children of a pool, we can optimize this task by
creating a new method in the PoolRepository class.
Story 2008873
Task 42414
Change-Id: Ie4d40509ae7e6faccecd1d0cc0bc4c7d93959261
(cherry picked from commit 7075d22c4c
)
This commit is contained in:
parent
46979a0d1b
commit
adb454b2e8
|
@ -2873,14 +2873,10 @@ class CountPoolChildrenForQuota(BaseDatabaseTask):
|
|||
:returns: None
|
||||
"""
|
||||
session = db_apis.get_session()
|
||||
db_pool = self.pool_repo.get(session, id=pool_id)
|
||||
LOG.debug("Counting pool children for "
|
||||
"project: %s ", db_pool.project_id)
|
||||
hm_count, member_count = (
|
||||
self.pool_repo.get_children_count(session, pool_id))
|
||||
|
||||
health_mon_count = 1 if db_pool.health_monitor else 0
|
||||
member_count = len(db_pool.members)
|
||||
|
||||
return {'HM': health_mon_count, 'member': member_count}
|
||||
return {'HM': hm_count, 'member': member_count}
|
||||
|
||||
|
||||
class DecrementL7policyQuota(BaseDatabaseTask):
|
||||
|
|
|
@ -1027,6 +1027,16 @@ class PoolRepository(BaseRepository):
|
|||
session, pagination_helper=pagination_helper,
|
||||
query_options=query_options, **filters)
|
||||
|
||||
def get_children_count(self, session, pool_id):
|
||||
hm_count = session.query(models.HealthMonitor).filter(
|
||||
models.HealthMonitor.pool_id == pool_id,
|
||||
models.HealthMonitor.provisioning_status != consts.DELETED).count()
|
||||
member_count = session.query(models.Member).filter(
|
||||
models.Member.pool_id == pool_id,
|
||||
models.Member.provisioning_status != consts.DELETED).count()
|
||||
|
||||
return (hm_count, member_count)
|
||||
|
||||
|
||||
class MemberRepository(BaseRepository):
|
||||
model_class = models.Member
|
||||
|
|
|
@ -2666,6 +2666,50 @@ class PoolRepositoryTest(BaseRepositoryTest):
|
|||
self.assertIsNone(self.hm_repo.get(self.session, pool_id=hm.pool_id))
|
||||
self.assertIsNone(self.sp_repo.get(self.session, pool_id=sp.pool_id))
|
||||
|
||||
def test_get_children_count(self):
|
||||
pool = self.create_pool(pool_id=self.FAKE_UUID_1,
|
||||
project_id=self.FAKE_UUID_2)
|
||||
hm_count, member_count = (
|
||||
self.pool_repo.get_children_count(self.session, pool.id))
|
||||
self.assertEqual(0, hm_count)
|
||||
self.assertEqual(0, member_count)
|
||||
|
||||
self.hm_repo.create(self.session, pool_id=pool.id,
|
||||
type=constants.HEALTH_MONITOR_HTTP,
|
||||
delay=1, timeout=1, fall_threshold=1,
|
||||
rise_threshold=1, enabled=True,
|
||||
provisioning_status=constants.ACTIVE,
|
||||
operating_status=constants.ONLINE)
|
||||
|
||||
hm_count, member_count = (
|
||||
self.pool_repo.get_children_count(self.session, pool.id))
|
||||
self.assertEqual(1, hm_count)
|
||||
self.assertEqual(0, member_count)
|
||||
|
||||
self.member_repo.create(self.session, id=self.FAKE_UUID_3,
|
||||
project_id=self.FAKE_UUID_2,
|
||||
pool_id=pool.id,
|
||||
ip_address="192.0.2.1",
|
||||
protocol_port=80,
|
||||
provisioning_status=constants.ACTIVE,
|
||||
operating_status=constants.ONLINE,
|
||||
enabled=True,
|
||||
backup=False)
|
||||
self.member_repo.create(self.session, id=self.FAKE_UUID_4,
|
||||
project_id=self.FAKE_UUID_2,
|
||||
pool_id=pool.id,
|
||||
ip_address="192.0.2.2",
|
||||
protocol_port=80,
|
||||
provisioning_status=constants.ACTIVE,
|
||||
operating_status=constants.ONLINE,
|
||||
enabled=True,
|
||||
backup=False)
|
||||
|
||||
hm_count, member_count = (
|
||||
self.pool_repo.get_children_count(self.session, pool.id))
|
||||
self.assertEqual(1, hm_count)
|
||||
self.assertEqual(2, member_count)
|
||||
|
||||
|
||||
class MemberRepositoryTest(BaseRepositoryTest):
|
||||
|
||||
|
|
|
@ -319,48 +319,24 @@ class TestDatabaseTasksQuota(base.TestCase):
|
|||
self.assertEqual(1, mock_lock_session.rollback.call_count)
|
||||
|
||||
@mock.patch('octavia.db.api.get_session')
|
||||
@mock.patch('octavia.db.repositories.PoolRepository.get')
|
||||
@mock.patch('octavia.db.repositories.PoolRepository.get_children_count')
|
||||
def test_count_pool_children_for_quota(self, repo_mock, session_mock):
|
||||
project_id = uuidutils.generate_uuid()
|
||||
member1 = data_models.Member(id=1, project_id=project_id)
|
||||
member2 = data_models.Member(id=2, project_id=project_id)
|
||||
healtmon = data_models.HealthMonitor(id=1, project_id=project_id)
|
||||
pool_no_children = data_models.Pool(id=1, project_id=project_id)
|
||||
pool_1_mem = data_models.Pool(id=1, project_id=project_id,
|
||||
members=[member1])
|
||||
pool_hm = data_models.Pool(id=1, project_id=project_id,
|
||||
health_monitor=healtmon)
|
||||
pool_hm_2_mem = data_models.Pool(id=1, project_id=project_id,
|
||||
health_monitor=healtmon,
|
||||
members=[member1, member2])
|
||||
pool = data_models.Pool(id=1, project_id=project_id)
|
||||
|
||||
task = database_tasks.CountPoolChildrenForQuota()
|
||||
|
||||
# Test pool with no children
|
||||
repo_mock.reset_mock()
|
||||
repo_mock.return_value = pool_no_children
|
||||
result = task.execute(pool_no_children.id)
|
||||
repo_mock.return_value = (0, 0)
|
||||
result = task.execute(pool.id)
|
||||
|
||||
self.assertEqual({'HM': 0, 'member': 0}, result)
|
||||
|
||||
# Test pool with one member
|
||||
repo_mock.reset_mock()
|
||||
repo_mock.return_value = pool_1_mem
|
||||
result = task.execute(pool_1_mem.id)
|
||||
|
||||
self.assertEqual({'HM': 0, 'member': 1}, result)
|
||||
|
||||
# Test pool with health monitor and no members
|
||||
repo_mock.reset_mock()
|
||||
repo_mock.return_value = pool_hm
|
||||
result = task.execute(pool_hm.id)
|
||||
|
||||
self.assertEqual({'HM': 1, 'member': 0}, result)
|
||||
|
||||
# Test pool with health monitor and two members
|
||||
repo_mock.reset_mock()
|
||||
repo_mock.return_value = pool_hm_2_mem
|
||||
result = task.execute(pool_hm_2_mem.id)
|
||||
repo_mock.return_value = (1, 2)
|
||||
result = task.execute(pool.id)
|
||||
|
||||
self.assertEqual({'HM': 1, 'member': 2}, result)
|
||||
|
||||
|
|
Loading…
Reference in New Issue