Created
April 3, 2015 23:21
-
-
Save Feuermurmel/3113d4fcc3d93b62549c to your computer and use it in GitHub Desktop.
retry.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
import sys, os, argparse, subprocess, time | |
class UserError(Exception): | |
def __init__(self, msg, *args): | |
super().__init__(msg.format(*args)) | |
def log(msg, *args): | |
print('{}: {}'.format(os.path.basename(sys.argv[0]), msg.format(*args)), file = sys.stderr) | |
def parse_args(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('command', nargs = argparse.REMAINDER, help = 'Command to execute.') | |
parser.add_argument('-i', '--min-interval', type = float, default = 10, help = 'Minimum time in seconds since the command has been started the last time before it is started again. Defaults to 10 seconds.') | |
parser.add_argument('-w', '--min-wait', type = float, default = 0, help = 'Minimum time in seconds after the command has terminated before it is started again. Defaults to no wait time.') | |
parser.add_argument('-r', '--restart-always', action = 'store_const', dest = 'restart', const = 'always', help = 'Restart the command whether it completes successfully or with a failure. By default, the command is only restarted until it succeeds.') | |
parser.add_argument('-R', '--restart-on-success', action = 'store_const', dest = 'restart', const = 'success', help = 'Restart the command as long as it succeeds.') | |
return parser.parse_args() | |
def main(): | |
args = parse_args() | |
start_time = 0 | |
min_wait = 0 | |
while True: | |
current_time = time.time() | |
start_time = max(start_time + args.min_interval, current_time + min_wait) | |
wait_time = start_time - current_time | |
if wait_time > 0: | |
log('Waiting {:.1f} seconds before restarting the command.', wait_time) | |
time.sleep(wait_time) | |
else: | |
start_time = current_time | |
process = subprocess.Popen(args.command) | |
process.wait() | |
if process.returncode: | |
log('Process exited with status {}.', process.returncode) | |
if args.restart == 'success': | |
raise UserError('Command failed with exit code {}.', process.returncode) | |
else: | |
if not args.restart: | |
break | |
min_wait = args.min_wait | |
try: | |
main() | |
except UserError as e: | |
log('Error: {}', e) | |
sys.exit(1) | |
except KeyboardInterrupt: | |
log('Operation interrupted.') | |
sys.exit(2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment