Allow changing lock purpose on lock upgrade

There may be a reason to change the 'purpose' of a lock,
for example performing a non-async deployment task on heartbeat
made through the new heartbeat API.
Allow changing the lock purpose on lock upgrade to have better logging.

Change-Id: Ife86e2b0dc74eaac7163000ea89cdb80a6cd3e87
This commit is contained in:
Pavlo Shchelokovskyy 2016-08-15 21:49:20 +03:00 committed by Ruby Loo
parent d447c1548f
commit 2a73b50a7f
2 changed files with 11 additions and 5 deletions

View File

@ -253,15 +253,19 @@ class TaskManager(object):
reserve_node()
def upgrade_lock(self):
def upgrade_lock(self, purpose=None):
"""Upgrade a shared lock to an exclusive lock.
Also reloads node object from the database.
Does nothing if lock is already exclusive.
If lock is already exclusive only changes the lock purpose
when provided with one.
:param purpose: optionally change the purpose of the lock
:raises: NodeLocked if an exclusive lock remains on the node after
"node_locked_retry_attempts"
"""
if purpose is not None:
self._purpose = purpose
if self.shared:
LOG.debug('Upgrading shared lock on node %(uuid)s for %(purpose)s '
'to an exclusive one (shared lock was held %(time).2f '

View File

@ -366,7 +366,7 @@ class TaskManagerTestCase(tests_db_base.DbTestCase):
node_get_mock.return_value = self.node
reserve_mock.return_value = self.node
with task_manager.TaskManager(self.context, 'fake-node-id',
shared=True) as task:
shared=True, purpose='ham') as task:
self.assertEqual(self.context, task.context)
self.assertEqual(self.node, task.node)
self.assertEqual(get_ports_mock.return_value, task.ports)
@ -377,9 +377,11 @@ class TaskManagerTestCase(tests_db_base.DbTestCase):
task.upgrade_lock()
self.assertFalse(task.shared)
# second upgrade does nothing
task.upgrade_lock()
self.assertEqual('ham', task._purpose)
# second upgrade does nothing except changes the purpose
task.upgrade_lock(purpose='spam')
self.assertFalse(task.shared)
self.assertEqual('spam', task._purpose)
build_driver_mock.assert_called_once_with(mock.ANY,
driver_name=None)