Change in vdsm[master]: Introducing context manager to terminate async processes on ...
ybronhei at redhat.com
ybronhei at redhat.com
Tue Jan 5 23:31:04 UTC 2016
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 <ybronhei at redhat.com>
---
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 <ybronhei at redhat.com>
More information about the vdsm-patches
mailing list