Optimize db.floating_ip_deallocate

'select for update' and 'update' operations
were combined into a single 'update' operation

problems with 'select for update' relate to
spec https://review.openstack.org/#/c/97310/1

now 'floating_ip_deallocate' function returns
number of updated rows in db

Partial-Bug: #1343613

Change-Id: I60f5a8f3e1541983dea1589783927107c00c5fa4
This commit is contained in:
pkholkin 2014-07-11 16:54:38 +04:00
parent c98ff96994
commit b8fe7b13cf
3 changed files with 15 additions and 18 deletions

View File

@ -905,21 +905,14 @@ def floating_ip_fixed_ip_associate(context, floating_address,
@_retry_on_deadlock
def floating_ip_deallocate(context, address):
session = get_session()
with session.begin():
floating_ip_ref = model_query(context, models.FloatingIp,
session=session).\
filter_by(address=address).\
filter(models.FloatingIp.project_id != null()).\
with_lockmode('update').\
first()
if floating_ip_ref:
floating_ip_ref.update({'project_id': None,
'host': None,
'auto_assigned': False})
return floating_ip_ref
return model_query(context, models.FloatingIp, session=session).\
filter_by(address=address).\
filter(models.FloatingIp.project_id != null()).\
update({'project_id': None,
'host': None,
'auto_assigned': False},
synchronize_session=False)
@require_context

View File

@ -278,10 +278,10 @@ class FloatingIP(object):
LOG.exception(_("Failed to update usages deallocating "
"floating IP"))
floating_ip_ref = objects.FloatingIP.deallocate(context, address)
# floating_ip_ref will be None if concurrently another
rows_updated = objects.FloatingIP.deallocate(context, address)
# number of updated rows will be 0 if concurrently another
# API call has also deallocated the same floating ip
if floating_ip_ref is None:
if not rows_updated:
if reservations:
QUOTAS.rollback(context, reservations, project_id=project_id)
else:

View File

@ -3894,13 +3894,17 @@ class FloatingIpTestCase(test.TestCase, ModelsObjectComparatorMixin):
def test_floating_ip_deallocate(self):
values = {'address': '1.1.1.1', 'project_id': 'fake', 'host': 'fake'}
float_ip = self._create_floating_ip(values)
db.floating_ip_deallocate(self.ctxt, float_ip.address)
rows_updated = db.floating_ip_deallocate(self.ctxt, float_ip.address)
self.assertEqual(1, rows_updated)
updated_float_ip = db.floating_ip_get(self.ctxt, float_ip.id)
self.assertIsNone(updated_float_ip.project_id)
self.assertIsNone(updated_float_ip.host)
self.assertFalse(updated_float_ip.auto_assigned)
def test_floating_ip_deallocate_address_not_found(self):
self.assertEqual(0, db.floating_ip_deallocate(self.ctxt, '2.2.2.2'))
def test_floating_ip_destroy(self):
addresses = ['1.1.1.1', '1.1.1.2', '1.1.1.3']
float_ips = [self._create_floating_ip({'address': addr})