You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.3 KiB
Python

"""
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()