File size: 1,976 Bytes
1905805
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import subprocess
import psutil
import logging

from .error import DuplicateLink, MissingLink

class BaseProcess(): # Be sure to make it a singleton (metaclass=Singleton)
    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):
        # This needs to be implemented
        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) # Add to links after loading process to ensure link established
        
    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()