| import subprocess |
| import psutil |
| import logging |
|
|
| from .error import DuplicateLink, MissingLink |
|
|
| class BaseProcess(): |
| id: str = None |
| process: subprocess.Popen = None |
| port: int = None |
| links: set = set() |
| |
| reload_signal: bool = False |
| unload_signal: bool = False |
| |
| def __init__(self, id): |
| self.id = id |
| |
| async def reload(self): |
| |
| self.reload_signal = False |
| |
| async def unload(self): |
| self.unload_signal = False |
| |
| if len(self.links): |
| logging.warning(f"Unloading process that still has the {len(self.links)} links") |
| logging.warning(f"Links: {self.links}") |
| |
| if self.process: |
| ps_process = psutil.Process(self.process.pid) |
| for child in ps_process.children(recursive=True): |
| child.kill() |
| ps_process.kill() |
| self.process = None |
| self.port = None |
| logging.info(f"Unloaded process {self.id}") |
| else: |
| logging.warning(f"Attempted to unload process {self.id} when it is already unloaded") |
| |
| async def link(self, link_id): |
| logging.debug("Adding link {} to process {}".format(link_id, self.id)) |
| if link_id in self.links: |
| raise DuplicateLink(link_id, self.id) |
| |
| if self.process is None: |
| await self.reload() |
| |
| self.links.add(link_id) |
| |
| async def unlink(self, link_id): |
| logging.debug("Removing link {} from process {}".format(link_id, self.id)) |
| if link_id not in self.links: |
| raise MissingLink(link_id, self.id) |
| self.links.remove(link_id) |
| |
| if len(self.links): |
| logging.info(f"No more links to process {self.id}. Unloading...") |
| await self.unload() |
|
|