""" The Management - this module takes care of loading and running subordinate bureaus in the office organization. Bureaus are enabled in the file "~/.screenless/mgmt.ini": [mgmt] bureaus = ihr typing myburo and so on """ import configparser import importlib import multiprocessing import os import signal import time class Management: """ Management is the executive of the Screenless Office. It can start, stop and reconfigure the subordinate bureaus of the office. """ def __init__(self): basepath = os.path.expanduser("~/.screenless") if not os.path.exists(basepath): os.mkdir(basepath) os.chdir(basepath) fontpath = os.path.join(basepath, "fonts") if not os.path.exists(fontpath): os.mkdir(fontpath) self.procs = {} self.org_chart = [] self._load_config() self.wait_restart = False def _load_config(self): config = configparser.ConfigParser() try: config.read("mgmt.ini") self.org_chart = config["mgmt"]["bureaus"].split() except KeyError: config["mgmt"] = {"bureaus": "ihr typing publicrelations photography jokes"} with open("mgmt.ini", "w") as configfile: config.write(configfile) print("Created new mgmt.ini config file. Please modify to suit.") self.org_chart = config["mgmt"]["bureaus"].split() def _start_bureaus(self): """ Initialized and start all child bureaus """ for buro in self.org_chart: self._start_bureau(buro) self.wait_restart = False def _start_bureau(self, bureau_name): """ starts an individual bureau """ lib = importlib.import_module("bureau." + bureau_name) proc = multiprocessing.Process(target=lib.main) self.procs[bureau_name] = proc proc.start() def _stop_bureaus(self): """ Terminates all running bureau children """ self.wait_restart = True for buro in self.org_chart: proc = self.procs[buro] proc.terminate() def reload(self, signum=None, frame=None): """ stop all bureaus, reload config, restart all bureaus. Note, this may cause a loss of state in some cases. """ self._stop_bureaus() self._load_config() self._start_bureaus() def run(self): """ main loop for Management, will restart crashed bureaus and reload everything when sent a SIGHUP """ with open("mgmt.pid", "w") as pfile: pfile.write(str(os.getpid())) signal.signal(signal.SIGHUP, self.reload) self._start_bureaus() while True: if self.wait_restart: time.sleep(1) continue for buro in self.org_chart: proc = self.procs[buro] if not proc.is_alive(): print("bureau", buro, "has crashed! Call the consultants!") time.sleep(3) print("restarting", buro) self._start_bureau(buro) time.sleep(1) if __name__ == "__main__": mgmt = Management() mgmt.run()