diff options
| author | Ivan A. Melnikov <imelnikov@griddynamics.com> | 2013-09-20 16:51:08 +0400 |
|---|---|---|
| committer | Ivan A. Melnikov <imelnikov@griddynamics.com> | 2013-10-04 12:10:27 +0400 |
| commit | 6134ff689a1d18a5ff23c3bb3fdcc140680f2387 (patch) | |
| tree | 9eeccaeaa8f372d51a23f498c9dd7931f4c5cb4c /taskflow/utils/persistence_utils.py | |
| parent | cde0dee14e0e93018f5d9a5a32a98623ec29bbc4 (diff) | |
| download | taskflow-6134ff689a1d18a5ff23c3bb3fdcc140680f2387.tar.gz | |
Wrapping and serializing failures
* save task failures to sqlalchemy backend and restore them
from there;
* for any wrapped exception use common WrappedFailre exception
type, which makes it easier to handle particular exception types;
* several minor improvements.
Affects-db: this change adds db migration that looses exception
information for saved task details.
Change-Id: I575282002e6999646bbf51f492b82a7e3525787a
Diffstat (limited to 'taskflow/utils/persistence_utils.py')
| -rw-r--r-- | taskflow/utils/persistence_utils.py | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/taskflow/utils/persistence_utils.py b/taskflow/utils/persistence_utils.py index 8f85050..63f7aea 100644 --- a/taskflow/utils/persistence_utils.py +++ b/taskflow/utils/persistence_utils.py @@ -22,6 +22,7 @@ import logging from taskflow.openstack.common import uuidutils from taskflow.persistence import logbook +from taskflow.utils import misc LOG = logging.getLogger(__name__) @@ -111,10 +112,13 @@ def task_details_merge(td_e, td_new, deep_copy=False): td_e.state = td_new.state if td_e.results != td_new.results: td_e.results = copy_fn(td_new.results) - if td_e.exception != td_new.exception: - td_e.exception = copy_fn(td_new.exception) - if td_e.stacktrace != td_new.stacktrace: - td_e.stacktrace = copy_fn(td_new.stacktrace) + if td_e.failure != td_new.failure: + # NOTE(imelnikov): we can't just deep copy Failures, as they + # contain tracebacks, which are not copyable. + if deep_copy: + td_e.failure = td_new.failure.copy() + else: + td_e.failure = td_new.failure if td_e.meta != td_new.meta: td_e.meta = copy_fn(td_new.meta) return td_e @@ -155,3 +159,33 @@ def logbook_merge(lb_e, lb_new, deep_copy=False): if lb_e.meta != lb_new.meta: lb_e.meta = copy_fn(lb_new.meta) return lb_e + + +def failure_to_dict(failure): + """Convert misc.Failure object to JSON-serializable dict""" + if not failure: + return None + if not isinstance(failure, misc.Failure): + raise TypeError('Failure object expected, but got %r' + % failure) + return { + 'exception_str': failure.exception_str, + 'traceback_str': failure.traceback_str, + 'exc_type_names': list(failure), + 'version': 1 + } + + +def failure_from_dict(data): + """Restore misc.Failure object from dict. + + The dict should be similar to what failure_to_dict() function + produces. + """ + if not data: + return None + version = data.pop('version', None) + if version != 1: + raise ValueError('Invalid version of saved Failure object: %r' + % version) + return misc.Failure(**data) |
