diff options
| author | Rick Harris <rconradharris@gmail.com> | 2012-02-29 23:38:56 +0000 |
|---|---|---|
| committer | Rick Harris <rconradharris@gmail.com> | 2012-03-01 22:13:03 -0600 |
| commit | c9aa0f57b6200313ea1f6c3839d65828024e2d37 (patch) | |
| tree | 279ca8081e6fa7dbb0cf9603b565e7bcdf611a77 /nova/utils.py | |
| parent | d65a4e4023e9994c8a14a1da4aa4eeb4f6452640 (diff) | |
| download | nova-c9aa0f57b6200313ea1f6c3839d65828024e2d37.tar.gz nova-c9aa0f57b6200313ea1f6c3839d65828024e2d37.tar.xz nova-c9aa0f57b6200313ea1f6c3839d65828024e2d37.zip | |
Refactor spawn to use UndoManager.
UndoManager provides a mechanism for automatically rolling back on
exceptions. An additional benefit of this approach is that undo code is
spatially close to the roll-forward code.
This patch should be considered an intermediate step towards a more
complete Command pattern based approach down the road.
Change-Id: Ib429420d67324422a5d13cdea6872fd9c57c857e
Diffstat (limited to 'nova/utils.py')
| -rw-r--r-- | nova/utils.py | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/nova/utils.py b/nova/utils.py index a224b3878..0ea6ee93b 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -1582,3 +1582,29 @@ def strcmp_const_time(s1, s2): for (a, b) in zip(s1, s2): result |= ord(a) ^ ord(b) return result == 0 + + +class UndoManager(object): + """Provides a mechanism to facilitate rolling back a series of actions + when an exception is raised. + """ + def __init__(self): + self.undo_stack = [] + + def undo_with(self, undo_func): + self.undo_stack.append(undo_func) + + def _rollback(self): + for undo_func in reversed(self.undo_stack): + undo_func() + + def rollback_and_reraise(self, msg=None): + """Rollback a series of actions then re-raise the exception. + + NOTE(sirp): This should only be called within an exception handler. + """ + with save_and_reraise_exception(): + if msg: + LOG.exception(msg) + + self._rollback() |
