shell_command: add ability to cancel a running process
Also adds an indefinite timeout if the timeout is specified as "None". Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
3d1faebf15
commit
6905515f3d
|
@ -19,6 +19,7 @@ class ShellCommand:
|
|||
cmd = os.path.expanduser(cmd)
|
||||
self.command = shlex.split(cmd)
|
||||
self.partial_output = b""
|
||||
self.cancelled = False
|
||||
|
||||
def _process_output(self, fd, events):
|
||||
if events & IOLoop.ERROR:
|
||||
|
@ -40,7 +41,14 @@ class ShellCommand:
|
|||
except Exception:
|
||||
logging.exception("Error writing command output")
|
||||
|
||||
def cancel(self):
|
||||
self.cancelled = True
|
||||
|
||||
async def run(self, timeout=2., verbose=True):
|
||||
fd = None
|
||||
if timeout is None:
|
||||
# Never timeout
|
||||
timeout = 9999999999999999.
|
||||
if not timeout or self.output_cb is None:
|
||||
# Fire and forget commands cannot be verbose as we can't
|
||||
# clean up after the process terminates
|
||||
|
@ -58,7 +66,7 @@ class ShellCommand:
|
|||
fd, self._process_output, IOLoop.READ | IOLoop.ERROR)
|
||||
elif not timeout:
|
||||
# fire and forget, return from execution
|
||||
return
|
||||
return True
|
||||
sleeptime = 0
|
||||
complete = False
|
||||
while sleeptime < timeout:
|
||||
|
@ -67,6 +75,8 @@ class ShellCommand:
|
|||
if proc.poll() is not None:
|
||||
complete = True
|
||||
break
|
||||
if self.cancelled:
|
||||
break
|
||||
if not complete:
|
||||
proc.terminate()
|
||||
if verbose:
|
||||
|
@ -75,10 +85,13 @@ class ShellCommand:
|
|||
self.partial_output = b""
|
||||
if complete:
|
||||
msg = f"Command ({self.name}) finished"
|
||||
elif self.cancelled:
|
||||
msg = f"Command ({self.name}) cancelled"
|
||||
else:
|
||||
msg = f"Command ({self.name}) timed out"
|
||||
logging.info(msg)
|
||||
self.io_loop.remove_handler(fd)
|
||||
return complete
|
||||
|
||||
class ShellCommandFactory:
|
||||
def build_shell_command(self, cmd, callback):
|
||||
|
|
Loading…
Reference in New Issue