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 commit7075d22c4c
) (cherry picked from commitadb454b2e8
) (cherry picked from commit37b15da4a1
)
This commit is contained in:
parent
d5dc2b2601
commit
4cfbf6669d
@ -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 UpdatePoolMembersOperatingStatusInDB(BaseDatabaseTask):
|
||||
|
@ -948,6 +948,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
|
||||
|
@ -2098,6 +2098,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):
|
||||
|
||||
|
@ -294,47 +294,23 @@ 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
Block a user