osm2city-scripts/worldbuild-runner.py
fly 4fbcce6303 Catch Ctrl+D as well
Signed-off-by: fly <merspieler@airmail.cc>
2021-04-07 16:30:31 +00:00

139 lines
3.9 KiB
Python
Executable file

#! /usr/bin/python3
# Copyright (C) 2018-2020 Merspieler, merspieler _at_ airmail.cc
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from time import sleep
from subprocess import Popen
from signal import SIGINT
import threading
import re
import sys
worker_cmd = ["./scripts/worldbuild-worker.py"]
argc = len(sys.argv)
i = 1
first = 1
while i < argc:
if sys.argv[i] == "-h" or sys.argv[i] == "--help":
print("usage: worldbuild-runner.py [OPTIONS] [WORKER-OPTIONS]")
print("Starts workers")
print("")
print(" -h, --help Shows this help and exit")
print("")
print("All other options get passed through to the worker")
sys.exit(0)
else:
worker_cmd.append(sys.argv[i])
i += 1
class launcher(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.running = []
self.stopping = []
self.run_count = 0
self.stop_count = 0
self.run_max = 0
self.stop = False
def run(self):
while not self.stop:
sleep(5)
i = 0
while i < self.stop_count:
if self.stopping[i].poll() != None:
del self.stopping[i]
self.stop_count -= 1
else: # Only increase by one if we don't delete the first element in the array
i += 1
i = 0
while i < self.run_count:
if self.running[i].poll() != None:
self.run_count -= 1
self.run_max -= 1
print("WARNING: Worker reported nothing to do. Reducing workers to " + str(self.run_max))
del self.running[i]
else: # Only increase by one if we don't delete the first element in the array
i += 1
while self.run_count + self.stop_count < self.run_max:
self.start_worker()
def set_proc_count(self, count):
if count > self.run_max:
while count > self.run_count + self.stop_count:
self.start_worker()
while count < self.run_count:
self.running[self.run_count - 1].send_signal(SIGINT)
self.stopping.append(self.running[self.run_count - 1])
del self.running[self.run_count - 1]
self.run_count -= 1
self.stop_count += 1
self.run_max = count
def start_worker(self):
self.running.append(Popen(worker_cmd, start_new_session=True))
self.run_count += 1
l = launcher()
l.start()
running = True
while running:
try:
cmd = input("> ")
if cmd == "quit":
running = False
break
elif cmd == "help":
print("Commands:")
print("help shows this help")
print("set workers <n> sets number of workers to <n>")
print("status shows number of running workers")
print("quit stops all workers, then exits")
elif cmd == "status" or cmd == "sts":
print("Current status:")
print("Max running: " + str(l.run_max))
print("Running: " + str(l.run_count))
print("Shutting down: " + str(l.stop_count))
else:
match = re.match("(set workers|sw) ([0-9]+)", cmd)
if match != None:
if match.group(1) == "set workers" or match.group(1) == "sw":
l.set_proc_count(int(match.group(2)))
else:
print("Invalid command. Type 'help' to see available commands")
except (KeyboardInterrupt, EOFError):
print("Please type 'quit' to exit the program")
l.set_proc_count(0)
shutting_down = True
while shutting_down:
try:
sleep(5)
if l.stop_count == 0 and l.run_count == 0:
shutting_down = False
l.stop = True
l.join()
except (KeyboardInterrupt, EOFError):
print("Please wait untill all workers are done")