import socketserver
from multiprocessing import Process, Value, Semaphore
from os import kill
from signal import SIGKILL


class FlowHandler:
    def __init__(self):
        self.value = Value("l", -1)
        self.value2 = Value("l", -1)
        self.signal = Semaphore(1)

    def handle(self):
        pass

    def handleRunning(self):
        pass

    def handleExit(self):
        pass

    def runFlow(self, signal, value, value2):
        """
        执行流程的代码
        """
        try:
            self.startRunningProcess()
            self.handle()
        finally:
            FlowHandler.resetValue(value)
            FlowHandler.resetValue(value2)
            self.stopRunningProcess()
            signal.release()

    def startRunningProcess(self):
        """
        在流程执行时，启动同步监控的代码
        """
        p = Process(target=self.handleRunning)
        p.start()
        with self.value2.get_lock():
            self.value2.value = p.pid

    @staticmethod
    def resetValue(value):
        """重置共享内存值为-1"""
        with value.get_lock():
            value.value = -1

    def stopRunningProcess(self):
        """流程进程结束时，同时也结束同步运行的进程"""
        with self.value2.get_lock():
            if self.value2.value != "-1":
                kill(self.value2.value, SIGKILL)
                FlowHandler.resetValue(self.value2)

    def create(self, value, value2, signal):
        """
        用于创建流程，每次只能创建一个，当上一个流程被终止或运行结束时，启动新的流程
        """
        while signal.acquire():
            process = Process(target=self.runFlow, args=[signal, value, value2])
            process.start()
            with value.get_lock():
                value.value = process.pid

    def createHandler(self):
        value = self.value
        value2 = self.value2
        signal = self.signal
        this = self
        p1 = Process(target=self.create, args=[value, value2, signal])  # 初始化"创建流程进程"以创建"流程进程"
        p1.start()

        class MyTCPHandler(socketserver.BaseRequestHandler):
            def handle(self):
                self.data = self.request.recv(1024).strip()
                if self.data.decode("utf-8") == str(value.value):
                    with value.get_lock():
                        pid = value.value
                        kill(value.value, SIGKILL)
                        value.value = -1
                        this.handleExit()
                        this.stopRunningProcess()
                        signal.release()  # 释放锁，以是的创建流程的进程激活以创建新的流程进程
                        self.request.sendall(b"OK,killed " + bytes(str(pid), "utf-8"))

        return MyTCPHandler

    def createServer(self, host, port):
        with socketserver.TCPServer((host, port), self.createHandler()) as server:
            print(f"Server started at tcp://{host}:{port}")
            server.serve_forever()


if __name__ == '__main__':
    import time


    class MyFlowHandler(FlowHandler):
        def handle(self):
            while True:
                time.sleep(1)
                print("hi")

        def handleExit(self):
            print("exit 0。。。")

        def handleRunning(self):
            while True:
                time.sleep(1)
                print("Running")


    MyFlowHandler().createServer("localhost", 8086)
