shell_command: allow callers to specify a "signal index"

Gives callers flexibility as to which signal is used to cancel a command first.  By default shell_command will start with SIGTERM, then proceed to SIGKILL.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Arksine 2021-03-29 07:29:41 -04:00
parent da9b9e184d
commit 9b0c9810a4
1 changed files with 14 additions and 8 deletions

View File

@ -48,12 +48,14 @@ class SCProcess(asyncio.subprocess.Process):
transport.close()
return output
async def cancel(self):
async def cancel(self, sig_idx=1):
if self.cancel_requested:
return
self.cancel_requested = True
exit_success = False
for sig in [signal.SIGINT, signal.SIGTERM, signal.SIGKILL]:
sig_idx = min(2, max(0, sig_idx))
sigs = [signal.SIGINT, signal.SIGTERM, signal.SIGKILL][sig_idx:]
for sig in sigs:
self.send_signal(sig)
try:
ret = self.wait()
@ -90,6 +92,9 @@ class SCProcess(asyncio.subprocess.Process):
await self.wait()
class ShellCommand:
IDX_SIGINT = 0
IDX_SIGTERM = 1
IDX_SIGKILL_= 2
def __init__(self, cmd, std_out_callback, std_err_callback,
env=None, log_stderr=False, cwd=None):
self.name = cmd
@ -104,10 +109,10 @@ class ShellCommand:
self.cancelled = False
self.return_code = None
async def cancel(self):
async def cancel(self, sig_idx=1):
self.cancelled = True
if self.proc is not None:
await self.proc.cancel()
await self.proc.cancel(sig_idx)
def get_return_code(self):
return self.return_code
@ -116,7 +121,8 @@ class ShellCommand:
self.return_code = self.proc = None
self.cancelled = False
async def run(self, timeout=2., verbose=True, log_complete=True):
async def run(self, timeout=2., verbose=True, log_complete=True,
sig_idx=1):
self._reset_command_data()
if not timeout:
# Never timeout
@ -135,13 +141,13 @@ class ShellCommand:
await asyncio.wait_for(ret, timeout=timeout)
except asyncio.TimeoutError:
complete = False
await self.proc.cancel()
await self.proc.cancel(sig_idx)
else:
complete = not self.cancelled
return self._check_proc_success(complete, log_complete)
async def run_with_response(self, timeout=2., retries=1,
log_complete=True):
log_complete=True, sig_idx=1):
self._reset_command_data()
retries = max(1, retries)
while retries > 0:
@ -153,7 +159,7 @@ class ShellCommand:
ret, timeout=timeout)
except asyncio.TimeoutError:
complete = False
await self.proc.cancel()
await self.proc.cancel(sig_idx)
else:
complete = not self.cancelled
if self.log_stderr and stderr: