From 82e2d0725d4e55b659fb788d6646f6ebd504fc9c Mon Sep 17 00:00:00 2001 From: Erik Olof Gunnar Andersson Date: Mon, 13 May 2019 18:04:15 -0700 Subject: 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. Change-Id: I0c7b45d3125ff1e007d44064a7653c1b2b07c770 (cherry picked from commit 6f13191a6c939d4f38955f8cb0a67f305b463bd1) --- designate/central/service.py | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/designate/central/service.py b/designate/central/service.py index f6f734d4..85ce106f 100644 --- a/designate/central/service.py +++ b/designate/central/service.py @@ -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): - ZONE_LOCKS.held.add(zone_id) - - # Call the wrapped function - result = f(self, *args, **kwargs) + with lockutils.lock(lock_name): + try: + ZONE_LOCKS.held.add(zone_id) + 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' -- cgit v1.2.1