Clean up zone locking

Updated the decorator to log something more appropriate when locking during
zone creation. The existing implementation would log 'zone-None', this
changes it to 'create-new-zone'.

We also add a try/finally catch statement to make sure the lock is always
released when done.

* Changed lock name to be more appropriate when creating new zones.
* Implement try/finally pattern to make sure lock is always released.

Depends-On: https://review.opendev.org/#/c/710243/
Change-Id: I0c7b45d3125ff1e007d44064a7653c1b2b07c770
This commit is contained in:
Erik Olof Gunnar Andersson 2019-05-13 18:04:15 -07:00 committed by Graham Hayes
parent f586e32192
commit 5bb39c18fb
No known key found for this signature in database
GPG Key ID: 1B263DC59F4AEFD5
1 changed files with 13 additions and 18 deletions

View File

@ -75,13 +75,10 @@ def synchronized_zone(zone_arg=1, new_zone=False):
if 'zone_id' in kwargs:
zone_id = kwargs['zone_id']
elif 'zone' in kwargs:
zone_id = kwargs['zone'].id
elif 'recordset' in kwargs:
zone_id = kwargs['recordset'].zone_id
elif 'record' in kwargs:
zone_id = kwargs['record'].zone_id
@ -91,43 +88,41 @@ def synchronized_zone(zone_arg=1, new_zone=False):
for arg in itertools.chain(kwargs.values(), args):
if isinstance(arg, objects.Zone):
zone_id = arg.id
if zone_id is not None:
if zone_id:
break
elif (isinstance(arg, objects.RecordSet) or
isinstance(arg, objects.Record) or
isinstance(arg, objects.ZoneTransferRequest) or
isinstance(arg, objects.ZoneTransferAccept)):
zone_id = arg.zone_id
if zone_id is not None:
if zone_id:
break
# If we still don't have an ID, find the Nth argument as
# defined by the zone_arg decorator option.
if zone_id is None and len(args) > zone_arg:
if not zone_id and len(args) > zone_arg:
zone_id = args[zone_arg]
if isinstance(zone_id, objects.Zone):
# If the value is a Zone object, extract it's ID.
zone_id = zone_id.id
if not new_zone and zone_id is None:
if new_zone and not zone_id:
lock_name = 'create-new-zone'
elif not new_zone and zone_id:
lock_name = 'zone-%s' % zone_id
else:
raise Exception('Failed to determine zone id for '
'synchronized operation')
if zone_id in ZONE_LOCKS.held:
# Call the wrapped function
return f(self, *args, **kwargs)
else:
with lockutils.lock('zone-%s' % zone_id):
with lockutils.lock(lock_name):
try:
ZONE_LOCKS.held.add(zone_id)
# Call the wrapped function
result = f(self, *args, **kwargs)
return f(self, *args, **kwargs)
finally:
ZONE_LOCKS.held.remove(zone_id)
return result
sync_wrapper.__wrapped_function = f
sync_wrapper.__wrapper_name = 'synchronized_zone'