Yaniv Bronhaim has uploaded a new change for review. Change subject: Introducing context manager to terminate async processes on internal fail ......................................................................
Introducing context manager to terminate async processes on internal fail part of the effort to omit the use of deathSignal. Change-Id: I003cce39d62dba5644937fafaf2c6e24c526c075 Signed-off-by: Yaniv Bronhaim <[email protected]> --- M lib/vdsm/utils.py 1 file changed, 44 insertions(+), 4 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/07/51407/1 diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py index 8288d5b..2a456ca 100644 --- a/lib/vdsm/utils.py +++ b/lib/vdsm/utils.py @@ -652,12 +652,14 @@ if not sync: p = AsyncProc(p) if data is not None: - p.stdin.write(data) - p.stdin.flush() + with terminator(p, execCmdLogger): + p.stdin.write(data) + p.stdin.flush() return p - (out, err) = p.communicate(data) + with terminator(p, execCmdLogger): + (out, err) = p.communicate(data) if out is None: # Prevent splitlines() from barfing later on @@ -685,7 +687,10 @@ nice=nice, ioclass=ioclass, execCmdLogger=execCmdLogger, deathSignal=deathSignal) - if not proc.wait(cond=stop): + with terminator(proc, execCmdLogger): + finished = proc.wait(cond=stop) + + if not finished: proc.kill() raise ActionStopped() @@ -697,6 +702,41 @@ return proc.returncode, out, err +def terminator(proc, logger): + ''' + A context manager for taking care for killing process on failure. + The first exception will be remembered and re-raised. + + Sample usage: + proc = ExecCmd('cmd', sync=False) + with terminator(proc, logger) as rollback: + ... + proc.communicate() + ... + ''' + def __init__(self, proc, log): + self._proc = proc + self._log = log + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + """ + If this function raises exception we re-raises the original exception + and kill the process finished. + """ + if exc_type is None and exc_value is None: + return + + exc_info = sys.exc_info() + try: + proc.kill() + except Exception: + self._log.error("Failed to kill subprocess") + six.reraise(*exc_info) + + def traceback(on="", msg="Unhandled exception"): """ Log a traceback for unhandled execptions. -- To view, visit https://gerrit.ovirt.org/51407 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I003cce39d62dba5644937fafaf2c6e24c526c075 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Yaniv Bronhaim <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
