| 101 | |
| 102 | |
| 103 | class Multiprocess: |
| 104 | def __init__( |
| 105 | self, |
| 106 | config: Config, |
| 107 | target: Callable[[list[socket] | None], None], |
| 108 | sockets: list[socket], |
| 109 | ) -> None: |
| 110 | self.config = config |
| 111 | self.target = target |
| 112 | self.sockets = sockets |
| 113 | |
| 114 | self.processes_num = config.workers |
| 115 | self.processes: list[Process] = [] |
| 116 | |
| 117 | self.should_exit = threading.Event() |
| 118 | |
| 119 | self.signal_queue: list[int] = [] |
| 120 | for sig in SIGNALS: |
| 121 | signal.signal(sig, lambda sig, frame: self.signal_queue.append(sig)) |
| 122 | |
| 123 | def init_processes(self) -> None: |
| 124 | for _ in range(self.processes_num): |
| 125 | process = Process(self.config, self.target, self.sockets) |
| 126 | process.start() |
| 127 | self.processes.append(process) |
| 128 | |
| 129 | def terminate_all(self) -> None: |
| 130 | for process in self.processes: |
| 131 | process.terminate() |
| 132 | |
| 133 | def join_all(self) -> None: |
| 134 | for process in self.processes: |
| 135 | process.join() |
| 136 | |
| 137 | def restart_all(self) -> None: |
| 138 | for idx, process in enumerate(self.processes): |
| 139 | process.terminate() |
| 140 | process.join() |
| 141 | new_process = Process(self.config, self.target, self.sockets) |
| 142 | new_process.start() |
| 143 | self.processes[idx] = new_process |
| 144 | |
| 145 | def run(self) -> None: |
| 146 | message = f"Started parent process [{os.getpid()}]" |
| 147 | color_message = "Started parent process [{}]".format(click.style(str(os.getpid()), fg="cyan", bold=True)) |
| 148 | logger.info(message, extra={"color_message": color_message}) |
| 149 | |
| 150 | self.init_processes() |
| 151 | |
| 152 | while not self.should_exit.wait(0.5): |
| 153 | self.handle_signals() |
| 154 | self.keep_subprocess_alive() |
| 155 | |
| 156 | self.terminate_all() |
| 157 | self.join_all() |
| 158 | |
| 159 | message = f"Stopping parent process [{os.getpid()}]" |
| 160 | color_message = "Stopping parent process [{}]".format(click.style(str(os.getpid()), fg="cyan", bold=True)) |
no outgoing calls